dotnet/runtime · error · Error
NotImplementedException
Error message
NotImplementedException ${element_type}. For more information see https://aka.ms/dotnet-wasm-jsinterop What it means
Thrown by _marshal_array_to_js_impl() as the final else when the C#-to-JS array element type does not match any supported type (String, Object, JSObject, Byte, Int32, Double, Single). This fires when C# returns an array with an element type that the JS marshaler cannot convert. The element_type value is included in the message along with a doc link.
Solutions
- Change the C# return type to a supported array type: string[], int[], byte[], double[], float[], or object[].
- For bool[], return byte[] (0/1) and convert on the JS side.
- For char[] or short[], return int[] and convert on the JS side.
- For long[], return a long[] if BigInt64 is supported, or return string[] with serialized values.
- Ensure the C# project and the JS runtime package are at compatible versions.
Example fix
// before (unsupported return type)
// C#: [JSExport] public static char[] GetData() { ... }
// after (supported return type)
// C#: [JSExport] public static int[] GetData() => chars.Select(c => (int)c).ToArray();
// JS: const chars = GetData().map(c => String.fromCharCode(c)); Defensive patterns
Strategy: validation
Validate before calling
// Validate C# return array type at design time // Only these array types are supported for C#-to-JS marshaling: const supportedReturnArrayTypes = ['string[]', 'int[]', 'byte[]', 'double[]', 'float[]', 'object[]']; // Ensure your JSExport/JSImport return types match this list
Prevention
- Return supported array types from C# JSExport methods: string[], int[], byte[], double[], float[], object[].
- Convert unsupported types (char[], short[], bool[], long[]) on the C# side before returning.
- Keep C# and JS runtime versions aligned to avoid marshaler mismatches.
When it happens
Trigger: A C# JSExport method returns an array whose element type is not one of the supported marshalable types (e.g., returns char[], short[], decimal[], long[], bool[]). The C#-side marshaler binding generates the element_type code, and _marshal_array_to_js_impl throws on unrecognized types.
Common situations: Returning unsupported array types from C# JSExport methods. Using a C# return type like char[] or long[] from an interop method. Version mismatch between the runtime and the C# signature generator.
Related errors
- not implemented
- JSObject proxy is not supported for
- NotImplementedException: ArraySegment. For more information…
- NotImplementedException: bigint
- NotImplementedException
AI-assisted analysis of dotnet/runtime@60108ba66e (2026-08-10).
Data as JSON: /api/errors/a1b25dda8727364c.
Report an issue: GitHub.
Appendix: source
Thrown at src/mono/browser/runtime/marshal-to-js.ts:544
}
} else if (element_type == MarshalerType.Byte) {
const bufferOffset = fixupPointer(buffer_ptr, 0);
const sourceView = localHeapViewU8().subarray(bufferOffset, bufferOffset + length);
result = sourceView.slice();//copy
} else if (element_type == MarshalerType.Int32) {
const bufferOffset = fixupPointer(buffer_ptr, 2);
const sourceView = localHeapViewI32().subarray(bufferOffset, bufferOffset + length);
result = sourceView.slice();//copy
} else if (element_type == MarshalerType.Double) {
const bufferOffset = fixupPointer(buffer_ptr, 3);
const sourceView = localHeapViewF64().subarray(bufferOffset, bufferOffset + length);
result = sourceView.slice();//copy
} else if (element_type == MarshalerType.Single) {
const bufferOffset = fixupPointer(buffer_ptr, 2);
const sourceView = localHeapViewF32().subarray(bufferOffset, bufferOffset + length);
result = sourceView.slice();//copy
} else {
throw new Error(`NotImplementedException ${element_type}. ${jsinteropDoc}`);
}
free(<any>buffer_ptr);
return result;
}
function _marshal_span_to_js (arg: JSMarshalerArgument, element_type?: MarshalerType): Span {
mono_assert(!!element_type, "Expected valid element_type parameter");
const buffer_ptr = get_arg_intptr(arg);
const length = get_arg_length(arg);
let result: Span | null = null;
if (element_type == MarshalerType.Byte) {
result = new Span(<any>buffer_ptr, length, MemoryViewType.Byte);
} else if (element_type == MarshalerType.Int32) {
result = new Span(<any>buffer_ptr, length, MemoryViewType.Int32);
} else if (element_type == MarshalerType.Double) {
result = new Span(<any>buffer_ptr, length, MemoryViewType.Double);
} else if (element_type == MarshalerType.Single) {View on GitHub (pinned to 60108ba66e)