dotnet/runtime · error · Error

NotImplementedException: bigint

Error message

NotImplementedException: bigint

What it means

Thrown by marshal_cs_object_to_cs() when a JS value of type 'bigint' (without a C# gc_handle) is passed to a C# method whose parameter is typed as 'object'. The runtime supports marshaling bigint to C# Int64 only when the parameter is explicitly typed as long/Int64 (via the BigInt64 marshaler). When the parameter is 'object', the marshaler does not know the target type and cannot convert an arbitrary-precision bigint, so it throws NotImplementedException. This is in the gc_handle === undefined branch.

Solutions

  1. Declare the C# parameter as 'long' (or 'long?' for nullable) instead of 'object' so the BigInt64 marshaler is used.
  2. Convert the bigint to a number before passing if the value fits in a safe integer: Number(value).
  3. Convert the bigint to a string and parse it on the C# side if precision is needed but the parameter must remain object.
  4. Wrap the value in a JS object and pass it as a JSObject proxy if you need an opaque handle.

Example fix

// before (C# method takes object, JS passes bigint)
// C#: [JSExport] public static void Foo(object value) { }
// JS:  Foo(123n); // throws NotImplementedException: bigint

// after (C# method takes long)
// C#: [JSExport] public static void Foo(long value) { }
// JS:  Foo(123n); // works via BigInt64 marshaler
Defensive patterns

Strategy: type-guard

Validate before calling

// Validate value type before passing to C# object parameter
function safeMarshal(value: any): any {
  if (typeof value === 'bigint') {
    // convert to number if safe, else throw with guidance
    if (value >= Number.MIN_SAFE_INTEGER && value <= Number.MAX_SAFE_INTEGER) {
      return Number(value);
    }
    throw new Error('BigInt too large for number; declare C# parameter as long instead of object');
  }
  return value;
}

Type guard

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

Prevention

When it happens

Trigger: Passing a JS bigint (e.g., 123n) to a C# method whose parameter is declared as 'object' rather than 'long' or 'Int64'. The marshal_cs_object_to_cs function is invoked because the C# signature uses MarshalerType.Object, and the js_type is 'bigint' which has no object marshaler.

Common situations: Using [JSImport] or [JSExport] with an 'object' parameter and passing a bigint from JS. Mixed-type APIs that accept object and receive bigint values. Confusion between C# long (which needs the specific marshaler) and object.

Related errors


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

Appendix: 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 60108ba66e)