dotnet/runtime · error · Error

NotImplementedException: bigint

Error message

NotImplementedException: bigint

What it means

In marshal_cs_object_to_cs, when a value is a JS bigint but the C# parameter is typed as object/JSObject (the generic object marshaler), the runtime throws because not every bigint fits in Int64 and the object marshaler has no bigint mapping. The dedicated long marshaler (setI64Big) handles bigints for strongly-typed long parameters, but the object path does not.

Source

Thrown at src/mono/browser/runtime/marshal-to-cs.ts:392

}

export function marshal_cs_object_to_cs (arg: JSMarshalerArgument, value: any): void {
    if (value === undefined || value === null) {
        set_arg_type(arg, MarshalerType.None);
        set_arg_proxy_context(arg);
    } else {
        const gc_handle = value[js_owned_gc_handle_symbol];
        const js_type = typeof (value);
        if (gc_handle === undefined) {
            if (js_type === "string" || js_type === "symbol") {
                set_arg_type(arg, MarshalerType.String);
                _marshal_string_to_cs_impl(arg, value);
            } else if (js_type === "number") {
                set_arg_type(arg, MarshalerType.Double);
                set_arg_f64(arg, value);
            } else if (js_type === "bigint") {
                // we do it because not all bigint values could fit into Int64
                throw new Error("NotImplementedException: bigint");
            } else if (js_type === "boolean") {
                set_arg_type(arg, MarshalerType.Boolean);
                set_arg_bool(arg, value);
            } else if (value instanceof Date) {
                set_arg_type(arg, MarshalerType.DateTime);
                set_arg_date(arg, value);
            } else if (value instanceof Error) {
                marshal_exception_to_cs(arg, value);
            } else if (value instanceof Uint8Array) {
                marshal_array_to_cs_impl(arg, value, MarshalerType.Byte);
            } else if (value instanceof Float32Array) {
                marshal_array_to_cs_impl(arg, value, MarshalerType.Single);
            } else if (value instanceof Float64Array) {
                marshal_array_to_cs_impl(arg, value, MarshalerType.Double);
            } else if (value instanceof Int32Array) {
                marshal_array_to_cs_impl(arg, value, MarshalerType.Int32);
            } else if (Array.isArray(value)) {
                marshal_array_to_cs_impl(arg, value, MarshalerType.Object);

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Declare the C# parameter as long or long? so the dedicated Int64 marshaler (setI64Big) is used.
  2. Convert the bigint to a Number (if within safe integer range), a string, or a byte array before passing.
  3. If you need arbitrary precision, marshal as a string and parse on the C# side.

Example fix

// C# before
[JSExport] public static void Take(object v) { }
// JS: dotnet.jsExports.Take(123n); // throws
// C# after
[JSExport] public static void Take(long v) { }
Defensive patterns

Strategy: type-guard

Validate before calling

if (typeof value === 'bigint') {
  throw new TypeError('Pass bigints only to C# long/long? parameters, not object/JSObject.');
}

Type guard

function isBigInt(v: unknown): v is bigint { return typeof v === 'bigint'; }

Try / catch

try { dotnet.jsExports.Take(value); } catch (e) { if (String(e?.message) === 'NotImplementedException: bigint') { /* coerce */ dotnet.jsExports.Take(Number(value)); } else throw e; }

Prevention

When it happens

Trigger: Passing a JS bigint to a [JSExport] C# parameter declared as object or JSObject instead of long/long?. The typeof === 'bigint' branch at line 390 throws.

Common situations: Mixing JS BigInt with loosely-typed C# interop; sending an int64-sized value as a generic object; JSON.parse producing numbers that the caller wraps in BigInt.

Related errors


AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06). Data as JSON: /api/errors/36b13ff7bdc5d223. Report an issue: GitHub.