{"record":{"id":"afe040bd0b951a89","repo":"dotnet/runtime","slug":"notimplementedexception-bigint-afe040","errorCode":null,"errorMessage":"NotImplementedException: bigint","messagePattern":"NotImplementedException: bigint","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts","lineNumber":363,"sourceCode":"}\n\nexport function marshalCsObjectToCs(arg: JSMarshalerArgument, value: any): void {\n    if (value === undefined || value === null) {\n        setArgType(arg, MarshalerType.None);\n        setArgProxyContext(arg);\n    } else {\n        const gcHandle = value[jsOwnedGcHandleSymbol];\n        const jsType = typeof (value);\n        if (gcHandle === undefined) {\n            if (jsType === \"string\" || jsType === \"symbol\") {\n                setArgType(arg, MarshalerType.String);\n                _marshalStringToCsImpl(arg, value);\n            } else if (jsType === \"number\") {\n                setArgType(arg, MarshalerType.Double);\n                setArgF64(arg, value);\n            } else if (jsType === \"bigint\") {\n                // we do it because not all bigint values could fit into Int64\n                throw new Error(\"NotImplementedException: bigint\");\n            } else if (jsType === \"boolean\") {\n                setArgType(arg, MarshalerType.Boolean);\n                setArgBool(arg, value);\n            } else if (value instanceof Date) {\n                setArgType(arg, MarshalerType.DateTime);\n                setArgDate(arg, value);\n            } else if (value instanceof Error) {\n                marshalExceptionToCs(arg, value);\n            } else if (value instanceof Uint8Array) {\n                marshalArrayToCsImpl(arg, value, MarshalerType.Byte);\n            } else if (value instanceof Float64Array) {\n                marshalArrayToCsImpl(arg, value, MarshalerType.Double);\n            } else if (value instanceof Float32Array) {\n                marshalArrayToCsImpl(arg, value, MarshalerType.Single);\n            } else if (value instanceof Int32Array) {\n                marshalArrayToCsImpl(arg, value, MarshalerType.Int32);\n            } else if (Array.isArray(value)) {\n                marshalArrayToCsImpl(arg, value, MarshalerType.Object);","sourceCodeStart":345,"sourceCodeEnd":381,"githubUrl":"https://github.com/dotnet/runtime/blob/290d5ab72cc1102813fbc0406fb186ceadabc340/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts#L345-L381","documentation":"Thrown by marshalCsObjectToCs when a JS value being marshaled to a C# 'object' parameter is a primitive bigint (typeof === 'bigint'). The generic object marshaler refuses bigint because arbitrary BigInt values do not always fit into a signed Int64; only the dedicated BigInt64 marshaler is supported. The comment in source explains the deliberate rejection.","triggerScenarios":"Calling a C# method whose parameter is typed `object` (or uses the default object marshaler) from JS and passing a BigInt literal such as 123n. Also hitting this path indirectly when an array of objects contains a bigint element.","commonSituations":"Passing large integer IDs or timestamps as JS BigInt to a C# interop method declared with `object` instead of `long`/`Int64`; returning bigint from a JS function imported into C# as returning object.","solutions":["Change the C# parameter/return type to `long` (Int64) and decorate with the BigInt64 marshaler so the dedicated marshaler path is used.","Convert the BigInt to a Number on the JS side (Number(value)) when you are sure it fits in safe-integer range.","If you need arbitrary precision, marshal the value as a string and parse it in C#."],"exampleFix":"// before\n[JSImport(\"globalThis.fns.getBig\")] // returns bigint\nstatic partial object GetBig();\n\n// after\n[JSImport(\"globalThis.fns.getBig\")]\n[return: JSMarshalAsAttribute<JSType.BigInt64>()]\nstatic partial long GetBig();","handlingStrategy":"type-guard","validationCode":"function toCsObject(value: unknown): unknown {\n    if (typeof value === \"bigint\") {\n        // bigint won't fit the object marshaler; convert or reject\n        const n = Number(value);\n        if (!Number.isSafeInteger(n)) throw new RangeError(\"bigint too large for number\");\n        return n;\n    }\n    return value;\n}","typeGuard":"const isSafeForCsObject = (v: unknown): boolean =>\n    v === null || v === undefined ||\n    [\"string\", \"number\", \"boolean\"].includes(typeof v) ||\n    v instanceof Date || v instanceof Error ||\n    Array.isArray(v) ||\n    v instanceof Uint8Array || v instanceof Int32Array ||\n    v instanceof Float32Array || v instanceof Float64Array;","tryCatchPattern":null,"preventionTips":["Type C# interop parameters explicitly (long/Int64 with BigInt64 marshaler) instead of object when bigints are involved.","Never pass raw BigInt literals to an object-typed interop API.","Unit-test the JS side's return types against the C# signatures."],"tags":["marshaling","bigint","interop","type-mismatch"],"analyzedSha":"290d5ab72cc1102813fbc0406fb186ceadabc340","analyzedAt":"2026-08-06T19:57:01.276Z","schemaVersion":2},"datasetVersion":"2026-08-06T23:17:07.152Z"}