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

  1. Change the C# return type to a supported array type: string[], int[], byte[], double[], float[], or object[].
  2. For bool[], return byte[] (0/1) and convert on the JS side.
  3. For char[] or short[], return int[] and convert on the JS side.
  4. For long[], return a long[] if BigInt64 is supported, or return string[] with serialized values.
  5. 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

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


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)