dotnet/runtime · error · Error

not implemented

Error message

not implemented

What it means

The terminal else branch of marshalArrayToCsImpl: the requested array elementType is none of String/Object/JSObject/Byte/Int32/Double/Single. The marshaler was asked to materialize an array of an element type for which no buffer-copy path exists.

Source

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

            const targetView = dotnetApi.localHeapViewU8().subarray(bufferOffset, bufferOffset + length);
            targetView.set(value);
        } else if (elementType == MarshalerType.Int32) {
            dotnetAssert.check(Array.isArray(value) || value instanceof Int32Array, "Value is not an Array or Int32Array");
            const bufferOffset = fixupPointer(bufferPtr, 2);
            const targetView = dotnetApi.localHeapViewI32().subarray(bufferOffset, bufferOffset + length);
            targetView.set(value);
        } else if (elementType == MarshalerType.Double) {
            dotnetAssert.check(Array.isArray(value) || value instanceof Float64Array, "Value is not an Array or Float64Array");
            const bufferOffset = fixupPointer(bufferPtr, 3);
            const targetView = dotnetApi.localHeapViewF64().subarray(bufferOffset, bufferOffset + length);
            targetView.set(value);
        } else if (elementType == MarshalerType.Single) {
            dotnetAssert.check(Array.isArray(value) || value instanceof Float32Array, "Value is not an Array or Float32Array");
            const bufferOffset = fixupPointer(bufferPtr, 2);
            const targetView = dotnetApi.localHeapViewF32().subarray(bufferOffset, bufferOffset + length);
            targetView.set(value);
        } else {
            throw new Error("not implemented");
        }
        setArgIntptr(arg, bufferPtr);
        setArgType(arg, MarshalerType.Array);
        setArgElementType(arg, elementType);
        setArgLength(arg, value.length);
    }
}

function _marshalSpanToCs(arg: JSMarshalerArgument, value: Span, elementType?: MarshalerType): void {
    dotnetAssert.check(!!elementType, "Expected valid elementType parameter");
    dotnetAssert.check(!value.isDisposed, "ObjectDisposedException");
    checkViewType(elementType, value._viewType);

    setArgType(arg, MarshalerType.Span);
    setArgIntptr(arg, value._pointer);
    setArgLength(arg, value.length);
}

View on GitHub (pinned to 290d5ab72c)

Solutions

  1. Use a supported element type for the array (byte[], int[], double[], float[], string[], object[], JSObject[]).
  2. For booleans/chars/enums, marshal as int or byte and convert in C#.
  3. Rebuild both sides to ensure MarshalerType enum values agree.

Example fix

// before
[return: JSMarshalAsAttribute<JSType.Array>()] // of bool
static partial bool[] GetFlags();

// after
[return: JSMarshalAsAttribute<JSType.Array<JSType.Byte>>()]
static partial byte[] GetFlags();
Defensive patterns

Strategy: validation

Validate before calling

const SUPPORTED_ARRAY_ELEMENT = new Set(["Byte","Int32","Double","Single","String","Object","JSObject"]);
function checkArrayElement(jsType: string) {
    if (!SUPPORTED_ARRAY_ELEMENT.has(jsType)) {
        throw new Error(`Unsupported array element type: ${jsType}`);
    }
}

Prevention

When it happens

Trigger: A C# signature declares an array of an unsupported element type (e.g. char[], bool[], DateTime[], an enum array, or a struct[]) routed through the generic array marshaler; or a wrong MarshalerType enum is passed due to a metadata bug.

Common situations: Declaring interop APIs with element types not in the supported set (Byte, Int32, Double, Single, String, Object, JSObject); version skew where a new MarshalerType value exists on one side only.

Related errors


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