mastra-ai/mastra · error · TypeError
The chunking RegExp must match a non-empty string.
Error message
The chunking RegExp must match a non-empty string.
What it means
When a RegExp is used as the chunking strategy, createChunkDetector builds the detected chunk as everything before the match plus the match itself. If that combined string is empty — only possible when the regex matches at index 0 and matches the empty string (a zero-width match) — no progress can be made splitting the buffer and the smoothing loop would stall, so the library throws a TypeError.
Source
Thrown at packages/core/src/stream/smooth-stream.ts:90
}
const pattern = typeof chunking === 'string' ? CHUNKING_PATTERNS[chunking] : chunking;
if (!(pattern instanceof RegExp)) {
throw new TypeError('chunking must be "word", "line", a RegExp, an Intl.Segmenter, or a chunk detector function.');
}
return buffer => {
pattern.lastIndex = 0;
const match = pattern.exec(buffer);
if (!match) {
return null;
}
const detected = buffer.slice(0, match.index) + match[0];
if (!detected.length) {
throw new TypeError('The chunking RegExp must match a non-empty string.');
}
return detected;
};
}
/**
* Creates a transform stream that buffers text and reasoning deltas and emits
* them in consistent, delayed chunks. Other stream parts pass through without
* modification after any buffered content has been emitted.
*
* @experimental This API may change in a future release.
*/
export function smoothStream<OUTPUT = undefined>({
delayInMs = 10,
chunking = 'word',
}: SmoothStreamOptions = {}): TransformStream<ChunkType<OUTPUT>, ChunkType<OUTPUT>> {
const detectChunk = createChunkDetector(chunking);View on GitHub (pinned to 75dd419e61)
Solutions
- Replace * with + quantifiers so the match consumes at least one character (e.g. /\s+/ instead of /\s*/).
- If splitting at boundaries, include the boundary character itself in the match (e.g. /[.,!?]\s/ instead of a lookahead alone).
- Test your regex against typical buffered text to confirm match[0].length > 0 for every possible match.
Example fix
// before
smoothStream({ model, chunking: /\s*/ }); // zero-width match -> throws
// after
smoothStream({ model, chunking: /\s+/ }); Defensive patterns
Strategy: validation
Validate before calling
function isNonEmptyMatchingRegex(re: RegExp, sample = 'a b c'): boolean {
re.lastIndex = 0;
const m = re.exec(sample);
return !!m && m[0].length > 0;
} Type guard
function matchIsNonEmpty(m: RegExpExecArray | null): m is RegExpExecArray {
return m !== null && m[0].length > 0;
} Try / catch
try {
streamText({ model, smoothStream: { chunking: myRegex } });
} catch (err) {
if (err instanceof TypeError && err.message.includes('RegExp must match a non-empty string')) {
console.error('regex has zero-width matches; replace * with + or include consumed chars');
} else throw err;
} Prevention
- Avoid * quantifiers and lookahead-only patterns in chunking regexes.
- Assert every possible match consumes ≥1 character.
- Test the regex against whitespace-only and punctuation-only buffers.
- Prefer + or explicit character classes over optional-only groups.
When it happens
Trigger: Calling smoothStream({ chunking: /someZeroWidthRegex/ }) where the pattern can match the empty string at the start of the buffer, e.g. /\s*/, /(?=\s)/, /x*/, or a regex composed entirely of optional groups.
Common situations: Writing split-on-boundary regexes with * instead of + quantifiers; using lookahead-only patterns; adapting a regex from another language where zero-width match semantics differed.
Related errors
- The chunking function must return a non-empty string.
- The chunking function must return a prefix of the buffered t
- chunking must be "word", "line", a RegExp, an Intl.Segmenter
- UI Messages require a data property when using data- prefixe
- UI Messages require a data property when using data- prefixe
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/9780fb84628e2cd4.
Report an issue: GitHub.