dotnet/runtime · error · Error

NotImplementedException: ArraySegment. For more information

Error message

NotImplementedException: ArraySegment. For more information see https://aka.ms/dotnet-wasm-jsinterop

What it means

Thrown by marshalCsObjectToCs when a value carries a GCHandle (i.e. it is a proxy created by C#) AND is an instance of the internal ArraySegment type, in the generic object marshaler. ArraySegment round-tripping through the object marshaler is intentionally not implemented; it must use the dedicated ArraySegment<T> marshaler.

Source

Thrown at src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts:406

                throw new Error("NotImplementedException: TypedArray");
            } else if (isThenable(value)) {
                marshalTaskToCs(arg, value);
            } else if (value instanceof Span) {
                throw new Error("NotImplementedException: Span");
            } else if (jsType == "object") {
                const jsHandle = getJsHandleFromJSObject(value);
                setArgType(arg, MarshalerType.JSObject);
                if (BuildConfiguration === "Debug" && Object.isExtensible(value)) {
                    value[proxyDebugSymbol] = `JS Object with JSHandle ${jsHandle}`;
                }
                setJsHandle(arg, jsHandle);
            } else {
                throw new Error(`JSObject proxy is not supported for ${jsType} ${value}`);
            }
        } else {
            assertNotDisposed(value);
            if (value instanceof ArraySegment) {
                throw new Error("NotImplementedException: ArraySegment. " + jsinteropDoc);
            } else if (value instanceof ManagedError) {
                setArgType(arg, MarshalerType.Exception);
                setGcHandle(arg, gcHandle);
            } else if (value instanceof ManagedObject) {
                setArgType(arg, MarshalerType.Object);
                setGcHandle(arg, gcHandle);
            } else {
                throw new Error("NotImplementedException " + jsType + ". " + jsinteropDoc);
            }
        }
    }
}

export function marshalArrayToCs(arg: JSMarshalerArgument, value: Array<any> | TypedArray | undefined | null, elementType?: MarshalerType): void {
    dotnetAssert.check(!!elementType, "Expected valid elementType parameter");
    marshalArrayToCsImpl(arg, value, elementType);
}

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Declare the C# parameter as ArraySegment<T> (e.g. ArraySegment<byte>) so the dedicated marshaler handles round-trip.
  2. If a generic carrier is required, copy the segment's data (slice/copyTo) into a byte[] and pass that.

Example fix

// before
static partial void Sink(object value); // passing ArraySegment<byte>

// after
static partial void Sink(ArraySegment<byte> value);
Defensive patterns

Strategy: validation

Validate before calling

function prepare(value: unknown): unknown {
    if (value && typeof value === "object" && "_pointer" in value && "array" in (value as any)) {
        throw new TypeError("ArraySegment must use the ArraySegment<T> marshaler, not object");
    }
    return value;
}

Type guard

const isArraySegmentLike = (v: unknown): boolean =>
    !!v && typeof v === "object" &&
    "_pointer" in (v as any) &&
    typeof (v as any).copyTo === "function";

Prevention

When it happens

Trigger: Receiving an ArraySegment<T> from one C# call and passing it into another C# method declared with `object` instead of ArraySegment<T>.

Common situations: Pooling/reusing ArraySegment instances across calls; declaring helper APIs with `object` parameters for flexibility, which routes them into the unsupported branch.

Related errors


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