You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
ReferenceError when resource has no functions #221
Calling new-join-set from a JavaScript guest fails with an error: ReferenceError: import_execution_1_0_0$JoinSetId is not defined.
This is because the generated initializer.jsdoes not contain class import_execution_1_0_0$JoinSetId {...}, but tries to use it in the generated new-join-set function: var rsc2 = new.target === import_execution_1_0_0$JoinSetId ? this : Object.create(import_execution_1_0_0$JoinSetId.prototype);
The workaround is to add a function, which triggers the class generation.
Tested with componentize-js version 0.18.2 .
Confirming this bug in 0.19.4-rc.1 with a different WASI interface: wasi:sockets/network (wasi:sockets@0.2.3).
wasi:sockets/network defines a single network resource with no methods. It is referenced by wasi:sockets/instance-network (instanceNetwork() returns a network) and by wasi:sockets/tcp (socket methods take borrow<network>). Neither of those interfaces defines the class — they just use it — so the class is never emitted and any guest code that calls instanceNetwork() or binds/connects a TCP socket throws at runtime:
ReferenceError: import_network_0_2_3$Network is not defined
import{instanceNetwork}from'wasi:sockets/instance-network@0.2.3';import{createTcpSocket}from'wasi:sockets/tcp-create-socket@0.2.3';exportconstrun={run(): void{constnetwork=instanceNetwork();// throws: import_network_0_2_3$Network is not definedconstsocket=createTcpSocket('ipv4');// ...},};
The generated bindings emit finalizationRegistry_import$network_0_2_3$network = new FinalizationRegistry(...) but never class import_network_0_2_3$Network { ... }. The class is only generated when the owning interface (wasi:sockets/network) has at least one callable function — since it has none, the class is skipped entirely.
Root cause
The issue is in spidermonkey-embedding-splicer. The class-generation code path is gated on the interface having callable functions; resource types in function-less interfaces fall through without a class definition. The class should be emitted for every imported resource, regardless of whether the owning interface has any callable functions.
JS-side workaround patch
While the right fix is in the splicer, here is a patch applied to componentize.js that works around the issue. It scans the generated bindings for finalization registries with no matching class and injects minimal class definitions after symbolDispose is declared:
This was developed while building a TypeScript wasmCloud service-and-component template that uses wasi:sockets for intra-workload TCP communication: wasmCloud/typescript#583
I reproduced this on 0.23.0 and 4d812f5. #357 fixes the missing class generation and adds a regression for returning, borrowing and disposing of a resource with no methods.
Activity
MendyBerger commentedon Jun 12, 2025
Running into the same issue with
wasi:graphics-context/graphics-context#abstract-buffer.It either gives a similar error to the one posted by the OP or sometimes even just hangs indefinitely without any errors.
Adding a simple
foo: func();to the resource gets it to work correctly.ericgregory commentedon Mar 19, 2026
Confirming this bug in
0.19.4-rc.1with a different WASI interface:wasi:sockets/network(wasi:sockets@0.2.3).wasi:sockets/networkdefines a singlenetworkresource with no methods. It is referenced bywasi:sockets/instance-network(instanceNetwork()returns anetwork) and bywasi:sockets/tcp(socket methods takeborrow<network>). Neither of those interfaces defines the class — they just use it — so the class is never emitted and any guest code that callsinstanceNetwork()or binds/connects a TCP socket throws at runtime:Minimal reproducer
WIT world:
TypeScript guest:
The generated bindings emit
finalizationRegistry_import$network_0_2_3$network = new FinalizationRegistry(...)but neverclass import_network_0_2_3$Network { ... }. The class is only generated when the owning interface (wasi:sockets/network) has at least one callable function — since it has none, the class is skipped entirely.Root cause
The issue is in
spidermonkey-embedding-splicer. The class-generation code path is gated on the interface having callable functions; resource types in function-less interfaces fall through without a class definition. The class should be emitted for every imported resource, regardless of whether the owning interface has any callable functions.JS-side workaround patch
While the right fix is in the splicer, here is a patch applied to
componentize.jsthat works around the issue. It scans the generated bindings for finalization registries with no matching class and injects minimal class definitions aftersymbolDisposeis declared:This was developed while building a TypeScript wasmCloud service-and-component template that uses
wasi:socketsfor intra-workload TCP communication: wasmCloud/typescript#583carsonfarmer commentedon Sep 26, 2026
I reproduced this on 0.23.0 and
4d812f5. #357 fixes the missing class generation and adds a regression for returning, borrowing and disposing of a resource with no methods.