vercel/ai · error
Chunking function must return a match that is a prefix of th
Error message
Chunking function must return a match that is a prefix of the buffer. Received: "${match}" expected to start with "${buffer}" What it means
Error thrown by smoothStream when the ChunkDetector returns a non-empty string that is NOT a prefix of the current buffer. The returned match must be the leading portion of the buffered text, since the stream trims exactly that prefix before continuing.
Source
Thrown at packages/ai/src/generate-text/smooth-stream.ts:75
if (buffer.length === 0) return null;
const iterator = segmenter.segment(buffer)[Symbol.iterator]();
const first = iterator.next().value;
return first?.segment || null;
};
} else if (typeof chunking === 'function') {
detectChunk = buffer => {
const match = chunking(buffer);
if (match == null) {
return null;
}
if (!match.length) {
throw new Error(`Chunking function must return a non-empty string.`);
}
if (!buffer.startsWith(match)) {
throw new Error(
`Chunking function must return a match that is a prefix of the buffer. Received: "${match}" expected to start with "${buffer}"`,
);
}
return match;
};
} else {
const chunkingRegex =
typeof chunking === 'string'
? CHUNKING_REGEXPS[chunking]
: chunking instanceof RegExp
? chunking
: undefined;
if (chunkingRegex == null) {
throw new InvalidArgumentError({
argument: 'chunking',
message: `Chunking must be "word", "line", a RegExp, an Intl.Segmenter, or a ChunkDetector function. Received: ${chunking}`,View on GitHub (pinned to 69428b1f8b)
Solutions
- Return the exact leading substring of the buffer, e.g. `buffer.slice(0, idx)`.
- Do not transform the match (trim/lowercase) before returning; emit null instead if the prefix isn't complete.
- If using a regex, anchor logic to `match.index === 0` and return `match[0]` only when it starts the buffer.
Example fix
// before
const chunking = (buffer: string) => buffer.trim(); // not a prefix if leading whitespace
// after
const chunking = (buffer: string) => {
const idx = buffer.search(/\s/);
return idx === -1 ? null : buffer.slice(0, idx);
}; Defensive patterns
Strategy: validation
Validate before calling
const detector = (buffer: string) => {
const m = computeChunk(buffer);
if (m != null && !buffer.startsWith(m)) return null; // enforce prefix invariant
return m;
}; Type guard
function isPrefixOfBuffer(m: string | null, buffer: string): m is string {
return m !== null && m.length > 0 && buffer.startsWith(m);
} Try / catch
try {
stream(fullStream.pipeThrough(smoothStream({ chunking: detector })));
} catch (e) {
if (e instanceof Error && e.message.startsWith('Chunking function must return a match')) {
// disable smoothing and pass raw stream through
} else throw e;
} Prevention
- Always slice the returned chunk out of the same buffer argument.
- Never transform (trim/lowercase) the detector result before returning.
- Add an assertion `buffer.startsWith(result)` in detector tests.
When it happens
Trigger: Custom detector returning text not at the buffer start — e.g. returning the whole buffer transformed, returning a lowercased/trimmed variant, returning match groups from the middle of the buffer, or returning a chunk computed from stale state.
Common situations: Detectors that normalize case or strip whitespace before returning; returning `match[1]` where the match isn't anchored at index 0; caching previous buffers and slicing incorrectly.
Related errors
- Chunking function must return a non-empty string.
- Chunking must be "word", "line", a RegExp, an Intl.Segmenter
- Chunking RegExp must not match an empty string.
- 'element streams in no-schema mode' functionality not suppor
- 'element streams in object mode' functionality not supported
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/f5ab81669a20cef7.
Report an issue: GitHub.