Skip to content

wit-parser panic on import + re-export of resource-bearing instance #2506

@ejrgilbert

Description

@ejrgilbert

wit_component::decode (and wasm-tools component wit) panic with assertion failed: prev.is_none() at wit-parser/src/decoding.rs:1085 when given a valid component that imports a resource-bearing interface and re-exports the same imported instance under a different name.

Repro

(component
    (type (;0;) (instance (export "request" (type (sub resource))))
    )
    (import "impl:test/handler" (instance (;0;) (type 0)))
    (export "wasi:http/handler@0.3.0" (instance 0))
)
$ wasm-tools parse repro.wat -o repro.wasm
$ wasm-tools validate --features=all repro.wasm
$ echo $?
0
$ wasm-tools component wit repro.wasm
thread 'main' panicked at /…/wit-parser-0.247.0/src/decoding.rs:1085:9:
assertion failed: prev.is_none()

Expected

The component validates as well-formed (wasm-tools validate --features=all exits 0), so wit-parser should either decode it successfully or return a structured Err, not panic.

Actual

WitPackageDecoder::register_type_export allocates a fresh TypeId for the re-exported request resource and inserts it into self.resources[owner][name]. The map already has an entry from the import-side decoding, so the assert!(prev.is_none()) on line 1085 fires. Backtrace tail:

wit_parser::decoding::WitPackageDecoder::register_type_export at decoding.rs:1085
wit_parser::decoding::WitPackageDecoder::register_import     at decoding.rs:821
wit_parser::decoding::WitPackageDecoder::decode_component_export at decoding.rs:724
wit_parser::decoding::ComponentInfo::decode_component        at decoding.rs:340
wit_parser::decoding::decode_reader                          at decoding.rs:404
wit_parser::decoding::decode                                 at decoding.rs:416

Why I hit this

I'm building a tool that generates a wrapper component around an existing component: the wrapper imports the original interface and re-exports it under the same canonical name (so downstream callers see no difference).
When the wrapped interface contains a resource (e.g. wasi:http/handler with request / response), wit_component::decode panics on the wrapper's bytes even though they validate cleanly. The minimal repro above is exactly that shape, stripped down to a single resource and a single wrapper-style re-export.

Versions

  • wasm-tools CLI: 1.247.0
  • wit-parser: 0.247.0
  • wit-component: 0.247.0

(haven't bisected to find the first affected version)

Notes

  • The same pattern with the resource type defined inline in the component (rather than imported from a sibling instance) decodes fine. It's specifically the alias chain through the import that confuses the resource-name registration.
  • A defensible fix would be to teach register_type_export to follow the alias chain and reuse the existing resource registration when the referenced type traces back to one already in self.resources[owner], instead of asserting.
  • Even if the fix is non-trivial, replacing the assert! with a structured bail! would let downstream tools recover gracefully.

Metadata

Metadata

Assignees

No one assigned

    Labels

    wit-parserIssues for the `wit-parser` crate

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions