dotnet/runtime · error · Error
JSObject proxy is not supported for
Error message
JSObject proxy is not supported for ${js_type} ${value} What it means
Thrown by marshal_cs_object_to_cs() when a JS value is passed to a C# 'object' parameter and its JS type does not match any recognized category. Specifically, this fires when js_type is 'function' (a JS function passed as object) or any other unusual type that falls through all instanceof checks in the gc_handle === undefined branch. The runtime cannot create a JSObject proxy for primitive types that are already handled elsewhere or for functions via this path.
Solutions
- Declare the C# parameter as Action or Func<T> (Delegate type) instead of 'object' so the function marshaler is used.
- Wrap the function in a plain object: { handler: fn } and access it via JSObject on the C# side.
- If C# must accept 'object', convert the function to a different representation (e.g., a string name or a wrapper object) before passing.
- Check the type of the value before passing and route it to the correct API overload.
Example fix
// before (function passed to object parameter)
// C#: [JSExport] public static void Register(object callback) { }
// JS: Register(() => console.log('hi')); // throws
// after (use Action parameter)
// C#: [JSExport] public static void Register(Action callback) { }
// JS: Register(() => console.log('hi')); // works via function marshaler Defensive patterns
Strategy: type-guard
Validate before calling
// Check if value is a function before passing to object parameter
function isFunction(value: any): boolean {
return typeof value === 'function';
}
if (isFunction(myValue)) {
// wrap in object or use Action/Func parameter instead
throw new Error('Use Action or Func parameter for JS functions, not object');
} Type guard
function isFunction(value: unknown): value is Function {
return typeof value === 'function';
} Prevention
- Declare C# parameters as Action or Func<T> for JS callbacks, not 'object'.
- Wrap functions in a plain object if you need to pass them as JSObject proxies.
- Validate the type of each argument before passing to interop methods.
When it happens
Trigger: Passing a raw JS function to a C# method whose parameter is 'object' (not Delegate or Function). The js_type is 'function', which doesn't match string/number/bigint/boolean/Date/Error/TypedArray/Array/Span/object checks, so it reaches the final throw at line 430.
Common situations: Passing a callback function where C# expects object instead of Action/Func. Using a loosely-typed C# API and passing unexpected JS types. Passing a Symbol or other exotic value type.
Related errors
- not implemented
- NotImplementedException: ArraySegment. For more information…
- NotImplementedException: bigint
- NotImplementedException
- NotImplementedException
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/f2b01c1111be44c9.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/marshal-to-cs.ts:430
|| value instanceof Int8Array
|| value instanceof Uint8ClampedArray
|| value instanceof Uint16Array
|| value instanceof Uint32Array
) {
throw new Error("NotImplementedException: TypedArray");
} else if (isThenable(value)) {
marshal_task_to_cs(arg, value);
} else if (value instanceof Span) {
throw new Error("NotImplementedException: Span");
} else if (js_type == "object") {
const js_handle = mono_wasm_get_js_handle(value);
set_arg_type(arg, MarshalerType.JSObject);
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);
}
}
}
}
View on GitHub (pinned to 60108ba66e)