dotnet/runtime · error · Error
NotImplementedException: Span
Error message
NotImplementedException: Span
What it means
Thrown by marshal_cs_object_to_cs() when a value that is instanceof Span (but does not have a C# gc_handle) is passed to a C# 'object' parameter. Span objects are created by the runtime when marshaling C# Span<T> to JS (via _marshal_span_to_js), but they are NOT registered as managed proxies (no setup_managed_proxy call). If you then try to pass such a Span back to C# as an 'object', the object marshaler does not know how to handle it. The proper way to pass a Span back is to declare the C# parameter as Span<T> with the correct element type.
Solutions
- Declare the C# receiving parameter as Span<T> (e.g., Span<byte>) with the matching element type so the _marshal_span_to_cs marshaler is used instead of the object marshaler.
- If you must use 'object', convert the Span to a TypedArray or byte[] before passing it: use the Span's underlying buffer.
- Keep the Span reference and pass it only to methods with explicit Span<T> parameters.
- Copy the Span data into a new Uint8Array/Int32Array/etc. and pass that array to the object parameter.
Example fix
// before (Span passed to object parameter)
// C#: [JSExport] public static void Consume(object data) { }
// JS: const span = GetSpanFromCSharp(); // returns Span
// Consume(span); // throws NotImplementedException: Span
// after (use Span<byte> parameter)
// C#: [JSExport] public static void Consume(Span<byte> data) { }
// JS: Consume(span); // works via _marshal_span_to_cs Defensive patterns
Strategy: type-guard
Validate before calling
// Check if value is a Span before passing to object parameter
function isSpan(value: any): boolean {
return value !== null && typeof value === 'object' && value.constructor && value.constructor.name === 'Span';
}
if (isSpan(myValue)) {
// extract data or use Span<T> parameter instead
const bytes = new Uint8Array(myValue._pointer, 0, myValue.length);
} Type guard
function isSpanLike(value: unknown): boolean {
return value !== null && typeof value === 'object'
&& '_pointer' in (value as any)
&& 'length' in (value as any)
&& '_viewType' in (value as any);
} Prevention
- Never pass a Span to a C# 'object' parameter; always use Span<T>.
- If you must pass Span data through a generic API, copy it to a Uint8Array first.
- Track which values are Span instances and route them to the correct typed parameter.
When it happens
Trigger: Receiving a Span<T> from a C# JSExport (which creates a JS-side Span wrapper), then passing it to another C# method whose parameter is 'object' instead of Span<T>. The gc_handle is undefined (Span is not a managed proxy), and instanceof Span is true at line 420.
Common situations: Chaining interop calls where a Span from one method is forwarded to another method with a different signature. Using a loosely-typed 'object' parameter to accept any value including a Span.
Related errors
- NotImplementedException
- JSObject proxy is not supported for
- not implemented
- NotImplementedException: ArraySegment. For more information…
- NotImplementedException: bigint
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/df964d4c90806893.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/marshal-to-cs.ts:421
} 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);
} else if (value instanceof Int16Array
|| value instanceof Int8Array
|| value instanceof Uint8ClampedArray
|| value instanceof Uint16Array
|| value instanceof Uint32Array
) {
throw new Error("NotImplementedException: TypedArray");
} else if (isThenable(value)) {
marshal_task_to_cs(arg, value);
} else if (value instanceof Span) {
throw new Error("NotImplementedException: Span");
} else if (js_type == "object") {
const js_handle = mono_wasm_get_js_handle(value);
set_arg_type(arg, MarshalerType.JSObject);
if (BuildConfiguration === "Debug" && Object.isExtensible(value)) {
value[proxy_debug_symbol] = `JS Object with JSHandle ${js_handle}`;
}
set_js_handle(arg, js_handle);
} else {
throw new Error(`JSObject proxy is not supported for ${js_type} ${value}`);
}
} else {
assert_not_disposed(value);
if (value instanceof ArraySegment) {
throw new Error("NotImplementedException: ArraySegment. " + jsinteropDoc);
} else if (value instanceof ManagedError) {
set_arg_type(arg, MarshalerType.Exception);
set_gc_handle(arg, gc_handle);
} else if (value instanceof ManagedObject) {View on GitHub (pinned to 60108ba66e)