{"record":{"id":"a7aabea2cc7b7c5d","repo":"dotnet/runtime","slug":"notimplementedexception-arraysegment-jsinterop","errorCode":null,"errorMessage":"NotImplementedException: ArraySegment. ${jsinteropDoc}","messagePattern":"NotImplementedException: ArraySegment\\. (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts","lineNumber":406,"sourceCode":"                throw new Error(\"NotImplementedException: TypedArray\");\n            } else if (isThenable(value)) {\n                marshalTaskToCs(arg, value);\n            } else if (value instanceof Span) {\n                throw new Error(\"NotImplementedException: Span\");\n            } else if (jsType == \"object\") {\n                const jsHandle = getJsHandleFromJSObject(value);\n                setArgType(arg, MarshalerType.JSObject);\n                if (BuildConfiguration === \"Debug\" && Object.isExtensible(value)) {\n                    value[proxyDebugSymbol] = `JS Object with JSHandle ${jsHandle}`;\n                }\n                setJsHandle(arg, jsHandle);\n            } else {\n                throw new Error(`JSObject proxy is not supported for ${jsType} ${value}`);\n            }\n        } else {\n            assertNotDisposed(value);\n            if (value instanceof ArraySegment) {\n                throw new Error(\"NotImplementedException: ArraySegment. \" + jsinteropDoc);\n            } else if (value instanceof ManagedError) {\n                setArgType(arg, MarshalerType.Exception);\n                setGcHandle(arg, gcHandle);\n            } else if (value instanceof ManagedObject) {\n                setArgType(arg, MarshalerType.Object);\n                setGcHandle(arg, gcHandle);\n            } else {\n                throw new Error(\"NotImplementedException \" + jsType + \". \" + jsinteropDoc);\n            }\n        }\n    }\n}\n\nexport function marshalArrayToCs(arg: JSMarshalerArgument, value: Array<any> | TypedArray | undefined | null, elementType?: MarshalerType): void {\n    dotnetAssert.check(!!elementType, \"Expected valid elementType parameter\");\n    marshalArrayToCsImpl(arg, value, elementType);\n}\n","sourceCodeStart":388,"sourceCodeEnd":424,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/native/libs/System.Runtime.InteropServices.JavaScript.Native/interop/marshal-to-cs.ts#L388-L424","documentation":"In the gcHandle-present branch of marshalCsObjectToCs, if the value is an ArraySegment instance the marshaler throws NotImplementedException. ArraySegment is only supported as a round-trip via the explicit ArraySegment marshaler (_marshalArraySegmentToCs), which requires the value to come from C# and be marshaled on a signature typed for ArraySegment - not through the generic object converter. The message appends jsinteropDoc (https://aka.ms/dotnet-wasm-jsinterop).","triggerScenarios":"An ArraySegment created by C# and handed to JS is later passed back through a parameter/return typed as object or JSObject (gcHandle present but the marshaler is the generic object one), hitting the explicit ArraySegment rejection.","commonSituations":"Storing an ArraySegment received from one interop call and forwarding it into another call whose parameter is typed object instead of ArraySegment<byte> etc.","solutions":["Type the C# parameter/return as ArraySegment<T> (with the right T: byte/int/double/float) so the value is routed through _marshalArraySegmentToCs.","Do not pass ArraySegment instances through object-typed interop boundaries.","If only the bytes are needed, extract a Span/byte[] view from the ArraySegment before crossing the object boundary."],"exampleFix":"// before - C#\n[JSImport(\"recv\", \"m\")]\nstatic partial void Receive([MarshalAs(typeof(object))] object seg);\n\n// after\n[JSImport(\"recv\", \"m\")]\nstatic partial void Receive(ArraySegment<byte> seg);","handlingStrategy":"type-guard","validationCode":"// Don't forward an ArraySegment through an object-typed boundary; copy out bytes.\nimport { ArraySegment } from \"./marshaled-types\";\n\nfunction arraySegmentToBytes(seg: ArraySegment): Uint8Array | null {\n  if (!(seg instanceof ArraySegment)) return null;\n  return seg.slice() as Uint8Array;\n}","typeGuard":"function isArraySegment(v: unknown): boolean {\n  return v instanceof ArraySegment;\n}","tryCatchPattern":"null","preventionTips":["Type C# interop params/returns as ArraySegment<T> to use _marshalArraySegmentToCs.","Never pass ArraySegment instances through object-typed interop boundaries.","Extract a byte[] view from an ArraySegment before crossing an object boundary.","Keep ArraySegment round-trips within explicitly typed call sites."],"tags":["jsinterop","marshaling","arraysegment","not-implemented"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}