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
- Declare the C# parameter as ArraySegment<T> (e.g. ArraySegment<byte>) so the dedicated marshaler handles round-trip.
- 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
- Type ArraySegment-carrying parameters explicitly as ArraySegment<T>.
- Avoid 'object' parameters on interop APIs that receive runtime-created proxies.
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
- NotImplementedException: ArraySegment. For more information
- NotImplementedException ${element_type}
- NotImplementedException: bigint
- NotImplementedException: TypedArray
- NotImplementedException: Span
AI-assisted analysis of dotnet/runtime@290d5ab72c (2026-08-06).
Data as JSON: /api/errors/dddc2073ca6b8327.
Report an issue: GitHub.