dotnet/runtime · error · Error
NotImplementedException
Error message
NotImplementedException ${js_type}. For more information see https://aka.ms/dotnet-wasm-jsinterop What it means
Thrown by marshal_cs_object_to_cs() when a value has a C# gc_handle (it is a managed proxy) but is not recognized as a ManagedError, ManagedObject, or ArraySegment. This is the catch-all in the gc_handle-defined branch. It indicates the value is some kind of managed proxy object whose concrete JS type the marshaler does not know how to handle through the generic 'object' path. The js_type is included in the message for diagnosis.
Solutions
- Check what type of object you are passing; use the correct C# parameter type (ManagedObject, specific class type) instead of 'object'.
- If the value should be a ManagedObject, ensure it was properly created by the runtime's managed proxy system.
- Update both the JS runtime and C# assemblies to matching versions to avoid unknown proxy types.
- Extract the underlying data from the proxy and pass primitive values instead.
- File an issue if the value is a standard managed object but still triggers this error, as it may be a marshaler bug.
Example fix
// before (unknown managed proxy passed to object)
// C#: [JSExport] public static void Handle(object proxy) { }
// JS: Handle(someUnknownManagedProxy); // throws
// after (use the correct type or pass a known value)
// C#: [JSExport] public static void Handle(ManagedObject proxy) { }
// or extract and pass primitive data instead of the proxy Defensive patterns
Strategy: type-guard
Validate before calling
// Validate that managed proxy values are known types before passing to object
function isKnownManagedProxy(value: any): boolean {
return value instanceof ManagedObject
|| value instanceof ManagedError
|| (value && value.constructor && value.constructor.name === 'ArraySegment');
}
if (!isKnownManagedProxy(myValue)) {
throw new Error('Unknown managed proxy type; check runtime and assembly versions');
} Type guard
function isManagedObject(value: unknown): value is ManagedObject {
return value !== null && typeof value === 'object' && js_owned_gc_handle_symbol in (value as any);
} Prevention
- Ensure the JS runtime and C# assemblies are from the same version/build.
- Use specific C# types (ManagedObject, ManagedError) instead of 'object' for managed proxies.
- Extract primitive data from proxies before passing to generic APIs.
When it happens
Trigger: Passing a managed proxy object (something created by C# and handed to JS with a gc_handle) to a C# 'object' parameter, where the proxy is not a standard ManagedObject, ManagedError, or ArraySegment. This could be a custom managed proxy type or a corrupted/unexpected proxy state.
Common situations: Using custom interop types that the marshaler does not recognize. Version skew between the JS runtime and the C# assemblies where a new proxy type exists on one side but not the other. Passing an internal runtime object (like a TaskHolder) as a regular object.
Related errors
- JSObject proxy is not supported for
- not implemented
- NotImplementedException: ArraySegment. For more information…
- NotImplementedException: bigint
- NotImplementedException
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/17ec63e194eb2e80.
Report an issue: GitHub.
Appendix: 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 60108ba66e)