{"record":{"id":"e7a7388fe6a53cf2","repo":"dotnet/runtime","slug":"jsobject-proxy-is-not-supported-for-jstype-va","errorCode":null,"errorMessage":"JSObject proxy is not supported for ${jsType} ${value}","messagePattern":"JSObject proxy is not supported for (.+?) (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts","lineNumber":401,"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                marshalTaskToCs(arg, value);\n            } else if (value instanceof Span) {\n                throw new Error(\"NotImplementedException: Span\");\n            } else if (jsType == \"object\") {\n                const jsHandle = getJsHandleFromJSObject(value);\n                setArgType(arg, MarshalerType.JSObject);\n                if (BuildConfiguration === \"Debug\" && Object.isExtensible(value)) {\n                    value[proxyDebugSymbol] = `JS Object with JSHandle ${jsHandle}`;\n                }\n                setJsHandle(arg, jsHandle);\n            } else {\n                throw new Error(`JSObject proxy is not supported for ${jsType} ${value}`);\n            }\n        } else {\n            assertNotDisposed(value);\n            if (value instanceof ArraySegment) {\n                throw new Error(\"NotImplementedException: ArraySegment. \" + jsinteropDoc);\n            } else if (value instanceof ManagedError) {\n                setArgType(arg, MarshalerType.Exception);\n                setGcHandle(arg, gcHandle);\n            } else if (value instanceof ManagedObject) {\n                setArgType(arg, MarshalerType.Object);\n                setGcHandle(arg, gcHandle);\n            } else {\n                throw new Error(\"NotImplementedException \" + jsType + \". \" + jsinteropDoc);\n            }\n        }\n    }\n}\n","sourceCodeStart":383,"sourceCodeEnd":419,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts#L383-L419","documentation":"In marshalCsObjectToCs, after handling primitives, Date, Error, known typed arrays, arrays, thenables, Span, and plain objects, the final else branch throws for any remaining JS type. In practice this is reached for values whose typeof is 'function' (a raw function passed where object marshaling is expected) because functions are not thenable and not otherwise matched in the gcHandle===undefined branch.","triggerScenarios":"Passing a JS function (callback) to a JSImport parameter that is typed as object/JSObject rather than as a delegate (Action/Func) marshaler; or returning a function from a JSImport whose return is typed object.","commonSituations":"Passing a callback where the C# signature expects object; forgetting to type a callback parameter as the right delegate marshaler so it falls into the object path.","solutions":["Type the C# parameter as the appropriate delegate (Action<...> / Func<...>) so it is routed through _marshalFunctionToCs instead of the object marshaler.","If you genuinely need to pass a callable to C#, wrap it so it is marshaled as a JSObject or a typed delegate, not as a bare object.","Avoid returning bare functions from interop methods typed as object; use a concrete delegate return type."],"exampleFix":"// before - C#\n[JSImport(\"setCb\", \"m\")]\nstatic partial void SetCallback([MarshalAs(typeof(object))] object cb);\n\n// after\n[JSImport(\"setCb\", \"m\")]\nstatic partial void SetCallback(Action<int> cb);","handlingStrategy":"type-guard","validationCode":"// Avoid passing a raw function through an object-typed boundary.\nfunction wrapCallback(fn: (...args: any[]) => any): object {\n  // return an object holder so it marshals as JSObject, or type the C# side as a delegate\n  return { invoke: fn } as object;\n}","typeGuard":"function isPlainFunction(v: unknown): boolean {\n  return typeof v === \"function\";\n}","tryCatchPattern":"null","preventionTips":["Type C# callback params as Action<...>/Func<...> delegates, not object.","Wrap bare functions in an object holder if you must marshal them as JSObject.","Never return bare functions from interop methods typed as object.","Audit interop signatures so callbacks use the delegate marshaler."],"tags":["jsinterop","marshaling","jsobject","function","not-supported"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}