{"record":{"id":"9f3295e6f5cfb20a","repo":"dotnet/runtime","slug":"notimplementedexception-elementtype","errorCode":null,"errorMessage":"NotImplementedException ${elementType} ","messagePattern":"NotImplementedException (.+?) ","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts","lineNumber":517,"sourceCode":"    dotnetAssert.check(gcHandle, \"Only roundtrip of ArraySegment instance created by C#\");\n    checkViewType(elementType, value._viewType);\n    setArgType(arg, MarshalerType.ArraySegment);\n    setArgIntptr(arg, value._pointer);\n    setArgLength(arg, value.length);\n    setGcHandle(arg, gcHandle);\n}\n\nfunction checkViewType(elementType: MarshalerType, viewType: MemoryViewType) {\n    if (elementType == MarshalerType.Byte) {\n        dotnetAssert.check(MemoryViewType.Byte == viewType, \"Expected MemoryViewType.Byte\");\n    } else if (elementType == MarshalerType.Int32) {\n        dotnetAssert.check(MemoryViewType.Int32 == viewType, \"Expected MemoryViewType.Int32\");\n    } else if (elementType == MarshalerType.Double) {\n        dotnetAssert.check(MemoryViewType.Double == viewType, \"Expected MemoryViewType.Double\");\n    } else if (elementType == MarshalerType.Single) {\n        dotnetAssert.check(MemoryViewType.Single == viewType, \"Expected MemoryViewType.Single\");\n    } else {\n        throw new Error(`NotImplementedException ${elementType} `);\n    }\n}\n\n","sourceCodeStart":499,"sourceCodeEnd":521,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts#L499-L521","documentation":"Thrown by checkViewType (called from _marshalSpanToCs and _marshalArraySegmentToCs) when the elementType is anything other than Byte, Int32, Double, or Single. Spans and ArraySegments are restricted to those four memory-view element kinds because the marshaler must map the element type to a fixed MemoryViewType for direct heap access; any other element kind is unsupported.","triggerScenarios":"A C# method accepts Span<T> or ArraySegment<T> with T other than byte/int/double/float (e.g. Span<char>, Span<long>, Span<nint>), and a JS caller invokes that interop boundary. Reached at marshal-to-cs.ts:517 when checkViewType cannot match the elementType to a MemoryViewType.","commonSituations":"Refactoring C# interop to use Span<char> for string-ish buffers, or Span<long>/Span<nint> assuming all primitive spans work. Trying to round-trip an ArraySegment<DateTimeOffset>. Updating to a runtime version that still has the four-type limit.","solutions":["Change the C# Span<T>/ArraySegment<T> element type to byte, int, double, or float.","For char data, use byte spans and encode/decode UTF-8 on the JS side with dotnetBrowserUtilsExports.stringToUTF8 / utf8ToString.","For 64-bit or other widths, marshal as an int[] or byte[] and widen on the C# side after the call."],"exampleFix":"// before (C#)\n[JSInvokable] public static void Fill(Span<char> buf) { /* ... */ } // throws NotImplementedException Char\n\n// after (C#)\n[JSInvokable] public static void Fill(Span<byte> utf8Buf) { /* decode UTF-8 on C# side */ }","handlingStrategy":"type-guard","validationCode":"const SUPPORTED_VIEW_ELEM = new Set(['Byte','Int32','Double','Single']);\n\nfunction isSupportedViewElement(elementType: string): boolean {\n  return SUPPORTED_VIEW_ELEM.has(elementType);\n}\n\nif (!isSupportedViewElement(csharpElementType)) {\n  throw new TypeError('Span/ArraySegment element type must be byte, int, double, or float');\n}","typeGuard":"type SupportedViewElement = 'Byte' | 'Int32' | 'Double' | 'Single';\nfunction isSupportedViewElement(t: string): t is SupportedViewElement {\n  return ['Byte','Int32','Double','Single'].includes(t);\n}","tryCatchPattern":"try {\n  fillSpan(spanProxy);\n} catch (e) {\n  if (e instanceof Error && e.message.startsWith('NotImplementedException ')) {\n    throw new TypeError('Span/ArraySegment element type not supported; use byte/int/double/float', { cause: e });\n  }\n  throw e;\n}","preventionTips":["Declare C# Span<T>/ArraySegment<T> interop only with byte/int/double/float.","Use byte spans + UTF-8 helpers for text buffers.","Keep the C# signature and runtime marshaler type table in sync."],"tags":["dotnet-wasm","jsinterop","marshaling","span","arraysegment","not-implemented"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}