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

  1. Return the exact leading substring of the buffer, e.g. `buffer.slice(0, idx)`.
  2. Do not transform the match (trim/lowercase) before returning; emit null instead if the prefix isn't complete.
  3. 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

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


AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30). Data as JSON: /api/errors/f5ab81669a20cef7. Report an issue: GitHub.