{"record":{"id":"291fd688a1c1ee0f","repo":"mastra-ai/mastra","slug":"the-chunking-function-must-return-a-prefix-of-the","errorCode":null,"errorMessage":"The chunking function must return a prefix of the buffered text.","messagePattern":"The chunking function must return a prefix of the buffered text\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/core/src/stream/smooth-stream.ts","lineNumber":67,"sourceCode":"      const firstSegment = chunking.segment(buffer)[Symbol.iterator]().next().value;\n      return firstSegment?.segment || null;\n    };\n  }\n\n  if (typeof chunking === 'function') {\n    return buffer => {\n      const match = chunking(buffer);\n\n      if (match == null) {\n        return null;\n      }\n\n      if (!match.length) {\n        throw new TypeError('The chunking function must return a non-empty string.');\n      }\n\n      if (!buffer.startsWith(match)) {\n        throw new TypeError('The chunking function must return a prefix of the buffered text.');\n      }\n\n      return match;\n    };\n  }\n\n  const pattern = typeof chunking === 'string' ? CHUNKING_PATTERNS[chunking] : chunking;\n\n  if (!(pattern instanceof RegExp)) {\n    throw new TypeError('chunking must be \"word\", \"line\", a RegExp, an Intl.Segmenter, or a chunk detector function.');\n  }\n\n  return buffer => {\n    pattern.lastIndex = 0;\n    const match = pattern.exec(buffer);\n\n    if (!match) {\n      return null;","sourceCodeStart":49,"sourceCodeEnd":85,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/core/src/stream/smooth-stream.ts#L49-L85","documentation":"createChunkDetector wraps a custom chunking function for smoothStream and verifies that any returned match is a prefix of the current text buffer. The smoothing machinery only consumes text from the front of the buffer; a match that is not a prefix could never be flushed in order, so the library throws a TypeError instead of corrupting or reordering the output stream.","triggerScenarios":"Calling smoothStream({ chunking: myFn }) where myFn(buffer) returns text that does not appear at position 0 of the buffer — e.g. returning buffer.slice(5, 10), returning a matched segment found mid-buffer, or returning a transformed/normalized version of the text.","commonSituations":"Custom detectors that search the whole buffer and return an interior match; detectors that return text after applying case/format transformations; reusing a detector designed for a different buffering scheme.","solutions":["Return buffer.slice(0, boundaryIndex) — always cut from the start of the buffer.","If the boundary is mid-buffer, either return the leading portion up to that boundary, or return null and let the buffer grow until the boundary reaches the front.","Never transform or re-case the returned text; return the exact leading substring of the buffer."],"exampleFix":"// before\nconst chunking = buffer => {\n  const idx = buffer.indexOf('|');\n  return idx === -1 ? null : buffer.slice(0, idx + 1).trim(); // trim may break prefix property\n};\n\n// after\nconst chunking = buffer => {\n  const idx = buffer.indexOf('|');\n  return idx === -1 ? null : buffer.slice(0, idx + 1);\n};","handlingStrategy":"validation","validationCode":"function isPrefixChunker(fn: (buf: string) => string | null): boolean {\n  const buf = 'hello world';\n  const out = fn(buf);\n  return out === null || buf.startsWith(out);\n}","typeGuard":"function isBufferPrefix(out: string | null, buffer: string): out is string {\n  return out !== null && buffer.startsWith(out);\n}","tryCatchPattern":"try {\n  streamText({ model, smoothStream: { chunking: myChunker } });\n} catch (err) {\n  if (err instanceof TypeError && err.message.includes('prefix of the buffered text')) {\n    console.error('chunker must return buffer.slice(0, n) — never interior or transformed text');\n  } else throw err;\n}","preventionTips":["Only return substrings cut from index 0 of the buffer.","Never trim/normalize the returned chunk.","When the boundary is mid-buffer, return null and wait for the buffer to advance, or return everything up to and including the boundary.","Property-test chunkers: out === null || buffer.startsWith(out)."],"tags":["streaming","smooth-stream","validation","typeerror"],"backgroundTag":"chunk-detector-not-a-prefix","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}