dotnet/runtime · error · Error
NotImplementedException ${js_type}. For more information see
Error message
NotImplementedException ${js_type}. For more information see https://aka.ms/dotnet-wasm-jsinterop What it means
The final else of the managed-proxy branch in marshal_cs_object_to_cs: the value carries a js_owned_gc_handle_symbol (so it is some kind of managed object proxy) but it is neither a ManagedError nor a ManagedObject, so the object marshaler does not know how to map it back. Typically indicates a version/runtime mismatch or a custom wrapper masquerading as a managed proxy.
Source
Thrown at src/mono/browser/runtime/marshal-to-cs.ts:443
if (BuildConfiguration === "Debug" && Object.isExtensible(value)) {
value[proxy_debug_symbol] = `JS Object with JSHandle ${js_handle}`;
}
set_js_handle(arg, js_handle);
} else {
throw new Error(`JSObject proxy is not supported for ${js_type} ${value}`);
}
} else {
assert_not_disposed(value);
if (value instanceof ArraySegment) {
throw new Error("NotImplementedException: ArraySegment. " + jsinteropDoc);
} else if (value instanceof ManagedError) {
set_arg_type(arg, MarshalerType.Exception);
set_gc_handle(arg, gc_handle);
} else if (value instanceof ManagedObject) {
set_arg_type(arg, MarshalerType.Object);
set_gc_handle(arg, gc_handle);
} else {
throw new Error("NotImplementedException " + js_type + ". " + jsinteropDoc);
}
}
}
}
export function marshal_array_to_cs (arg: JSMarshalerArgument, value: Array<any> | TypedArray | undefined | null, element_type?: MarshalerType): void {
mono_assert(!!element_type, "Expected valid element_type parameter");
marshal_array_to_cs_impl(arg, value, element_type);
}
export function marshal_array_to_cs_impl (arg: JSMarshalerArgument, value: Array<any> | TypedArray | undefined | null, element_type: MarshalerType): void {
if (value === null || value === undefined) {
set_arg_type(arg, MarshalerType.None);
} else {
const element_size = array_element_size(element_type);
mono_assert(element_size != -1, () => `Element type ${element_type} not supported`);
const length = value.length;
const buffer_length = element_size * length;View on GitHub (pinned to 290d5ab72c)
Solutions
- Ensure the JS and C# runtime versions match exactly (rebuild/redeploy both sides).
- Do not attach or copy internal proxy symbols onto custom objects.
- If holding a stale proxy from a previous runtime init, discard it and obtain a fresh reference.
Example fix
// before // reusing a managed proxy object captured before a runtime restart dotnet.jsExports.Take(staleManagedObjectProxy); // throws // after // re-fetch the managed object from the current runtime instance
Defensive patterns
Strategy: validation
Validate before calling
// Treat any object carrying the internal managed-proxy symbol as runtime-bound; do not reuse across inits.
if (value && typeof value === 'object' && Object.getOwnPropertySymbols(value).some(s => String(s).includes('gc_handle'))) {
console.warn('Passing a possible stale managed proxy; ensure runtime versions match and references are fresh.');
} Prevention
- Keep JS and C# runtime builds in lockstep.
- Never copy internal proxy symbols onto unrelated objects.
- Discard managed proxies obtained before a runtime restart and fetch fresh references.
When it happens
Trigger: Passing an object that has the managed-proxy symbol but is not a recognized ManagedObject/ManagedError instance to an object-typed C# parameter.
Common situations: Mixing runtime versions where proxy class identity changed; a third-party wrapper that copies internal proxy symbols onto unrelated objects; stale references from a previous runtime instance.
Related errors
- NotImplementedException: bigint
- NotImplementedException: TypedArray
- NotImplementedException: Span
- JSObject proxy is not supported for ${js_type} ${value}
- NotImplementedException: ArraySegment. For more information
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/17ec63e194eb2e80.
Report an issue: GitHub.