dotnet/runtime · error · Error
NotImplementedException: bigint
Error message
NotImplementedException: bigint
What it means
marshalCsObjectToCs handles a JS value of type 'bigint' when the value has no jsOwnedGcHandleSymbol (i.e. it is a raw bigint being marshaled as a generic object, not a managed Int64). The marshaler does not attempt to coerce arbitrary-precision bigints into a .NET object and throws NotImplementedException. Use a typed Int64/Int52 parameter or BigInt64 marshaler instead.
Solutions
- Declare the C# signature with an explicit long/Int64 (or long[]) parameter/return and the BigInt64 marshaler so the value goes through _marshalBigint64ToCs instead of the object path.
- If the value may exceed Int64 range, convert it to a string in JS and parse on the C# side (long.Parse / BigInteger.Parse).
- Avoid returning raw bigints from interop functions typed as object; pick a concrete primitive or JSObject marshaling.
Example fix
// before - C#
[return: MarshalAs(typeof(object))]
[JSImport("big", "m")]
static partial object Big(); // JS returns BigInt(123) -> throws
// after
[return: MarshalAs(typeof(long))]
[JSImport("big", "m")]
static partial long Big(); // routed through BigInt64 marshaler Defensive patterns
Strategy: type-guard
Validate before calling
// On the JS side, avoid returning a raw bigint through an object-typed boundary.
function safeReturn(value: unknown): unknown {
if (typeof value === "bigint") {
// marshal as Int64-friendly value or string
return value.toString(); // parse with long.Parse / BigInteger.Parse on C# side
}
return value;
} Type guard
function isBigint(v: unknown): v is bigint {
return typeof v === "bigint";
} Try / catch
null
Prevention
- Declare C# interop params/returns as long/Int64 with the BigInt64 marshaler instead of object.
- Convert bigints to strings in JS when the C# side uses object/string typing.
- Do not pass bigints into object[]-typed interop params.
- Audit third-party JS return values that may be bigints before crossing interop.
When it happens
Trigger: A JS function invoked from C# via JSImport returns or passes a JS bigint in a position typed as `object`/JSObject (marshalCsObjectToCs path) rather than a parameter explicitly marshaled as BigInt64/Int64. For example returning BigInt(...) from a JS function whose [return: ...] is object.
Common situations: Returning BigInt(...) from a JS interop function while the C# side declares the return as object or lacks the explicit [return: MarshalAs(... BigInt64)]; passing a bigint into a params object[] array; third-party JS lib returning bigints through interop.
Related errors
- not implemented
- NotImplementedException: ArraySegment.
- NotImplementedException
- NotImplementedException
- NotImplementedException
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/afe040bd0b951a89.
Report an issue: GitHub.
Appendix: source
Thrown at src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts:363
}
export function marshalCsObjectToCs(arg: JSMarshalerArgument, value: any): void {
if (value === undefined || value === null) {
setArgType(arg, MarshalerType.None);
setArgProxyContext(arg);
} else {
const gcHandle = value[jsOwnedGcHandleSymbol];
const jsType = typeof (value);
if (gcHandle === undefined) {
if (jsType === "string" || jsType === "symbol") {
setArgType(arg, MarshalerType.String);
_marshalStringToCsImpl(arg, value);
} else if (jsType === "number") {
setArgType(arg, MarshalerType.Double);
setArgF64(arg, value);
} else if (jsType === "bigint") {
// we do it because not all bigint values could fit into Int64
throw new Error("NotImplementedException: bigint");
} else if (jsType === "boolean") {
setArgType(arg, MarshalerType.Boolean);
setArgBool(arg, value);
} else if (value instanceof Date) {
setArgType(arg, MarshalerType.DateTime);
setArgDate(arg, value);
} else if (value instanceof Error) {
marshalExceptionToCs(arg, value);
} else if (value instanceof Uint8Array) {
marshalArrayToCsImpl(arg, value, MarshalerType.Byte);
} else if (value instanceof Float64Array) {
marshalArrayToCsImpl(arg, value, MarshalerType.Double);
} else if (value instanceof Float32Array) {
marshalArrayToCsImpl(arg, value, MarshalerType.Single);
} else if (value instanceof Int32Array) {
marshalArrayToCsImpl(arg, value, MarshalerType.Int32);
} else if (Array.isArray(value)) {
marshalArrayToCsImpl(arg, value, MarshalerType.Object);View on GitHub (pinned to 60108ba66e)