{"record":{"id":"663690a015671e19","repo":"denoland/deno","slug":"err-invalid-state-663690","errorCode":"ERR_INVALID_STATE","errorMessage":"Invalid state: Cannot validate on a detached buffer","messagePattern":"Invalid state: Cannot validate on a detached buffer","errorType":"error_code","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/buffer.mjs","lineNumber":3166,"sourceCode":"}\n\n// deno-lint-ignore camelcase\nfunction writeU_Int24LE(buf, value, offset, min, max) {\n  value = +value;\n  checkInt(value, min, max, buf, offset, 2);\n\n  buf[offset++] = value;\n  value = value >>> 8;\n  buf[offset++] = value;\n  value = value >>> 8;\n  buf[offset++] = value;\n  return offset;\n}\n\nfunction isUtf8(input) {\n  if (isTypedArray(input)) {\n    if (isDetachedBuffer(TypedArrayPrototypeGetBuffer(input))) {\n      throw new ERR_INVALID_STATE(\"Cannot validate on a detached buffer\");\n    }\n    return op_is_utf8(input);\n  }\n\n  if (isAnyArrayBuffer(input)) {\n    if (isDetachedBuffer(input)) {\n      throw new ERR_INVALID_STATE(\"Cannot validate on a detached buffer\");\n    }\n    return op_is_utf8(new Uint8Array(input));\n  }\n\n  throw new codes.ERR_INVALID_ARG_TYPE(\"input\", [\n    \"ArrayBuffer\",\n    \"Buffer\",\n    \"TypedArray\",\n  ], input);\n}\n","sourceCodeStart":3148,"sourceCodeEnd":3184,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/buffer.mjs#L3148-L3184","documentation":"Buffer.isUtf8(input) checks whether bytes form valid UTF-8. When input is a TypedArray whose underlying ArrayBuffer has been detached (moved away via a transfer), the data no longer exists and validation is impossible, so ERR_INVALID_STATE is thrown instead of returning a boolean. Detaching happens with structuredClone(..., { transfer }) or Worker/MessagePort postMessage transfer lists.","triggerScenarios":"const v = new Uint8Array(n); structuredClone(v, { transfer: [v.buffer] }); Buffer.isUtf8(v); - also after worker.postMessage(buf, [buf.buffer]) and then re-validating on the sending side.","commonSituations":"Zero-copy pipelines that transfer buffers to workers and keep validating the now-empty local view; views cached across async boundaries where another code path transferred the buffer; ownership bugs where both sides assume they still hold the data.","solutions":["Validate only on the receiving side of the transfer - the sender's view is dead after transfer","Guard first: if (view.buffer.detached) skip - ArrayBuffer.prototype.detached is available in Deno","Drop the transfer list when the data is still needed locally: structuredClone(view) copies instead of moving","Keep a copy before transferring and validate the copy"],"exampleFix":"// before\nconst view = new Uint8Array([0xf0]);\nstructuredClone(view, { transfer: [view.buffer] });\nBuffer.isUtf8(view); // ERR_INVALID_STATE: Cannot validate on a detached buffer\n\n// after\nconst clone = structuredClone(view); // keep local copy\nstructuredClone(view, { transfer: [view.buffer] });\nBuffer.isUtf8(clone);","handlingStrategy":"type-guard","validationCode":"function isUtf8Safe(view) {\n  if (!(view instanceof Uint8Array)) throw new TypeError('expected Uint8Array');\n  if (view.buffer.detached) return null; // data moved elsewhere\n  return Buffer.isUtf8(view);\n}","typeGuard":"const isLiveView = (v) => v instanceof Uint8Array && !v.buffer.detached;","tryCatchPattern":"try {\n  ok = Buffer.isUtf8(view);\n} catch (e) {\n  if (e?.code === 'ERR_INVALID_STATE') { ok = null; /* buffer was transferred */ }\n  else throw e;\n}","preventionTips":["Validate before transferring, or only on the receiving side","Check the detached property whenever a view crosses a transfer boundary","Model buffer ownership explicitly - exactly one side reads after handoff"],"tags":["buffer","detached-buffer","transfer","workers","encoding","utf8"],"backgroundTag":"detached-arraybuffer","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}