dotnet/runtime · error · Error

NotImplementedException ${elementType}. For more information

Error message

NotImplementedException ${elementType}. For more information see https://aka.ms/dotnet-wasm-jsinterop

What it means

Thrown by the C#-to-JS array marshaler (_marshalArrayToJs) when elementType is none of String/Object/JSObject/Byte/Int32/Double/Single. It is the JS-side mirror of the array marshaler else branch: the runtime tried to materialize a JS array from a managed array of an unsupported element type.

Source

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

        }
    } else if (elementType == MarshalerType.Byte) {
        const bufferOffset = fixupPointer(bufferPtr, 0);
        const sourceView = dotnetApi.localHeapViewU8().subarray(bufferOffset, bufferOffset + length);
        result = sourceView.slice();//copy
    } else if (elementType == MarshalerType.Int32) {
        const bufferOffset = fixupPointer(bufferPtr, 2);
        const sourceView = dotnetApi.localHeapViewI32().subarray(bufferOffset, bufferOffset + length);
        result = sourceView.slice();//copy
    } else if (elementType == MarshalerType.Double) {
        const bufferOffset = fixupPointer(bufferPtr, 3);
        const sourceView = dotnetApi.localHeapViewF64().subarray(bufferOffset, bufferOffset + length);
        result = sourceView.slice();//copy
    } else if (elementType == MarshalerType.Single) {
        const bufferOffset = fixupPointer(bufferPtr, 2);
        const sourceView = dotnetApi.localHeapViewF32().subarray(bufferOffset, bufferOffset + length);
        result = sourceView.slice();//copy
    } else {
        throw new Error(`NotImplementedException ${elementType}. ${jsinteropDoc}`);
    }
    Module._free(<any>bufferPtr);
    return result;
}

function _marshalSpanToJs(arg: JSMarshalerArgument, elementType?: MarshalerType): Span {
    dotnetAssert.check(!!elementType, "Expected valid elementType parameter");

    const bufferPtr = getArgIntptr(arg);
    const length = getArgLength(arg);
    let result: Span | null = null;
    if (elementType == MarshalerType.Byte) {
        result = new Span(<any>bufferPtr, length, MemoryViewType.Byte);
    } else if (elementType == MarshalerType.Int32) {
        result = new Span(<any>bufferPtr, length, MemoryViewType.Int32);
    } else if (elementType == MarshalerType.Double) {
        result = new Span(<any>bufferPtr, length, MemoryViewType.Double);
    } else if (elementType == MarshalerType.Single) {

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Return one of the supported array types (byte[], int[], double[], float[], string[], object[], JSObject[]).
  2. Box or convert unsupported element types before returning (e.g. bool[] -> byte[], char[] -> int[]).

Example fix

// before
[return: JSMarshalAsAttribute<JSType.Array<JSType.Char>>()]
static partial char[] GetText();

// after
[return: JSMarshalAsAttribute<JSType.Array<JSType.Int32>>()]
static partial int[] GetText();
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED = new Set(["Byte","Int32","Double","Single","String","Object","JSObject"]);
function checkReturnArray(jsType: string) {
    if (!SUPPORTED.has(jsType)) throw new Error(`Cannot return array of ${jsType} to JS`);
}

Prevention

When it happens

Trigger: A C# method declared with [return: JSMarshalAsAttribute<JSType.Array<...>>] using an unsupported inner element type, or a JS-visible field/property of an unsupported array element kind.

Common situations: Returning char[], bool[], DateTime[], enum[], or struct[] arrays to JS; mismatched JSType generic arguments between the attribute and the actual type.

Related errors


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