{"record":{"id":"f2b01c1111be44c9","repo":"dotnet/runtime","slug":"jsobject-proxy-is-not-supported-for-js-type-v","errorCode":null,"errorMessage":"JSObject proxy is not supported for ${js_type} ${value}","messagePattern":"JSObject proxy is not supported for (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/marshal-to-cs.ts","lineNumber":430,"sourceCode":"                || value instanceof Int8Array\n                || value instanceof Uint8ClampedArray\n                || value instanceof Uint16Array\n                || value instanceof Uint32Array\n            ) {\n                throw new Error(\"NotImplementedException: TypedArray\");\n            } else if (isThenable(value)) {\n                marshal_task_to_cs(arg, value);\n            } else if (value instanceof Span) {\n                throw new Error(\"NotImplementedException: Span\");\n            } else if (js_type == \"object\") {\n                const js_handle = mono_wasm_get_js_handle(value);\n                set_arg_type(arg, MarshalerType.JSObject);\n                if (BuildConfiguration === \"Debug\" && Object.isExtensible(value)) {\n                    value[proxy_debug_symbol] = `JS Object with JSHandle ${js_handle}`;\n                }\n                set_js_handle(arg, js_handle);\n            } else {\n                throw new Error(`JSObject proxy is not supported for ${js_type} ${value}`);\n            }\n        } else {\n            assert_not_disposed(value);\n            if (value instanceof ArraySegment) {\n                throw new Error(\"NotImplementedException: ArraySegment. \" + jsinteropDoc);\n            } else if (value instanceof ManagedError) {\n                set_arg_type(arg, MarshalerType.Exception);\n                set_gc_handle(arg, gc_handle);\n            } else if (value instanceof ManagedObject) {\n                set_arg_type(arg, MarshalerType.Object);\n                set_gc_handle(arg, gc_handle);\n            } else {\n                throw new Error(\"NotImplementedException \" + js_type + \". \" + jsinteropDoc);\n            }\n        }\n    }\n}\n","sourceCodeStart":412,"sourceCodeEnd":448,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/marshal-to-cs.ts#L412-L448","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before (function passed to object parameter)\n// C#: [JSExport] public static void Register(object callback) { }\n// JS:  Register(() => console.log('hi')); // throws\n\n// after (use Action parameter)\n// C#: [JSExport] public static void Register(Action callback) { }\n// JS:  Register(() => console.log('hi')); // works via function marshaler","handlingStrategy":"type-guard","validationCode":"// Check if value is a function before passing to object parameter\nfunction isFunction(value: any): boolean {\n  return typeof value === 'function';\n}\n\nif (isFunction(myValue)) {\n  // wrap in object or use Action/Func parameter instead\n  throw new Error('Use Action or Func parameter for JS functions, not object');\n}","typeGuard":"function isFunction(value: unknown): value is Function {\n  return typeof value === 'function';\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["marshaling","type-mismatch","function","interop"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}