{"record":{"id":"c0be4e2140f73df5","repo":"denoland/deno","slug":"err-string-too-long","errorCode":"ERR_STRING_TOO_LONG","errorMessage":"Cannot create a string longer than 0x${maxStringLengthHex} characters","messagePattern":"Cannot create a string longer than 0x(.+?) characters","errorType":"exception","errorClass":"NodeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/string_decoder.ts","lineNumber":118,"sourceCode":"        isTA\n          ? TypedArrayPrototypeGetBuffer(buf)\n          : DataViewPrototypeGetBuffer(buf),\n        isTA\n          ? TypedArrayPrototypeGetByteOffset(buf)\n          : DataViewPrototypeGetByteOffset(buf),\n        isTA\n          ? TypedArrayPrototypeGetByteLength(buf)\n          : DataViewPrototypeGetByteLength(buf),\n      ),\n    );\n  }\n}\n\nconst maxStringLengthHex = NumberPrototypeToString(MAX_STRING_LENGTH, 16);\nfunction bufferToString(buf, encoding, start, end) {\n  const len = (end ?? buf.length) - (start ?? 0);\n  if (len > MAX_STRING_LENGTH) {\n    throw new NodeError(\n      \"ERR_STRING_TOO_LONG\",\n      `Cannot create a string longer than 0x${maxStringLengthHex} characters`,\n    );\n  }\n  // deno-lint-ignore deno-internal/prefer-primordials -- buf is a Buffer; Buffer.prototype.toString(encoding) is not String.prototype.toString\n  return buf.toString(encoding, start, end);\n}\n\nconst kBufferedBytes = Symbol(\"bufferedBytes\");\nconst kMissingBytes = Symbol(\"missingBytes\");\n\nfunction decode(buf) {\n  const enc = this.enc;\n\n  let bufIdx = 0;\n  let bufEnd = buf.length;\n\n  let prepend = \"\";","sourceCodeStart":100,"sourceCodeEnd":136,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/string_decoder.ts#L100-L136","documentation":"Thrown by Deno's node:string_decoder polyfill when a single conversion would produce a string longer than V8's MAX_STRING_LENGTH (about 0x1fffffe8, roughly 536.8 million characters). bufferToString() computes the requested span (end - start, defaulting to the whole buffer) and refuses the conversion up front, because V8 cannot allocate a JS string that large. Node.js throws the same ERR_STRING_TOO_LONG guard when creating strings from oversized buffers.","triggerScenarios":"Calling new StringDecoder(encoding).write(buf) or .end(buf) with a Buffer/TypedArray whose length (or end-start span) exceeds MAX_STRING_LENGTH: decoding a multi-hundred-MB file read with fs.readFileSync in one call, or accumulating network chunks into one giant buffer before decoding it as a single string.","commonSituations":"Reading whole large files (logs, dumps, media) into memory and decoding in one shot; merging streamed chunks into a single buffer before conversion; processing very large base64/hex payloads in one piece; test fixtures that accidentally reference huge binaries.","solutions":["Decode incrementally: feed the StringDecoder fixed-size chunks (e.g. 1 MiB) with decoder.write() as data arrives, then decoder.end() at the end — partial multi-byte characters at chunk edges are buffered correctly","Stream the source instead of buffering: for await (const chunk of fs.createReadStream(path)) text += decoder.write(chunk)","If you already hold one huge buffer, loop over subarray(i, i + MAX) slices and decode each slice separately","For base64/hex input, convert in chunks and avoid materializing the fully decoded output as one JS string at all"],"exampleFix":"// before\nconst text = new StringDecoder('utf8').end(fs.readFileSync('huge.bin'));\n\n// after\nconst dec = new StringDecoder('utf8');\nlet text = '';\nfor await (const chunk of fs.createReadStream('huge.bin')) {\n  text += dec.write(chunk);\n}\ntext += dec.end();","handlingStrategy":"validation","validationCode":"// V8 max string length guard (matches MAX_STRING_LENGTH, ~2**29 - 24)\nconst MAX_STRING = 2 ** 29 - 24;\n\nfunction decodeSafe(decoder, buf) {\n  if (buf.length <= MAX_STRING) {\n    return decoder.write(buf) + decoder.end();\n  }\n  let out = '';\n  for (let i = 0; i < buf.length; i += MAX_STRING) {\n    out += decoder.write(buf.subarray(i, i + MAX_STRING));\n  }\n  return out + decoder.end();\n}","typeGuard":null,"tryCatchPattern":"try {\n  text = decoder.end(hugeBuf);\n} catch (err) {\n  if (err?.code === 'ERR_STRING_TOO_LONG') {\n    // fall back to chunked decoding\n    text = decodeSafe(decoder, hugeBuf);\n  } else {\n    throw err;\n  }\n}","preventionTips":["Never decode an unbounded buffer in one call — stream sources with fs.createReadStream and feed StringDecoder.write per chunk","Cap accumulated buffer size before converting; treat ~512 MiB as the hard ceiling for a single JS string","Remember encodings expand or shrink data (hex doubles size, base64 shrinks) — budget the decoded length, not the input length","Prefer pipeline/stream APIs over readFileSync for any file whose size you do not control"],"tags":["buffer","encoding","string-decoder","memory","node-compat"],"backgroundTag":"max-string-length-exceeded","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}