mastra-ai/mastra · error · TypeError
The chunking function must return a non-empty string.
Error message
The chunking function must return a non-empty string.
What it means
createChunkDetector wraps a custom chunking function for smoothStream. The wrapped detector validates the function's return value: it must return a string, and if it returns a match it must be non-empty. An empty string cannot be used to split the buffered text, so the library throws a TypeError immediately instead of producing an empty chunk that would cause an infinite loop in the smoothing loop.
Source
Thrown at packages/core/src/stream/smooth-stream.ts:63
if (!buffer) {
return null;
}
const firstSegment = chunking.segment(buffer)[Symbol.iterator]().next().value;
return firstSegment?.segment || null;
};
}
if (typeof chunking === 'function') {
return buffer => {
const match = chunking(buffer);
if (match == null) {
return null;
}
if (!match.length) {
throw new TypeError('The chunking function must return a non-empty string.');
}
if (!buffer.startsWith(match)) {
throw new TypeError('The chunking function must return a prefix of the buffered text.');
}
return match;
};
}
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;View on GitHub (pinned to 75dd419e61)
Solutions
- Return null (not '') from your chunking function when no boundary should be emitted this tick.
- Ensure any returned match has at least one character; adjust your regex to require content (use \s+ not \s*, avoid zero-width matches).
- Add a guard in your chunking function: if (match.length === 0) return null;
Example fix
// before
const chunking = buffer => buffer.match(/\s*/) ?? null; // can return ''
// after
const chunking = buffer => {
const m = buffer.match(/\s+/);
return m ? m[0] : null;
}; Defensive patterns
Strategy: validation
Validate before calling
function isValidChunker(fn: (buf: string) => string | null): boolean {
const out = fn('sample text boundary');
return out === null || out.length > 0;
} Type guard
function returnsNonEmptyOrNull(v: unknown): v is string | null {
return v === null || (typeof v === 'string' && v.length > 0);
} Try / catch
try {
streamText({ model, smoothStream: { chunking: myChunker } });
} catch (err) {
if (err instanceof TypeError && err.message.includes('non-empty string')) {
console.error('chunker returned empty string; fix to return null instead');
} else throw err;
} Prevention
- Always return null, never '', for 'no boundary yet'.
- Use + quantifiers instead of * in boundary regexes to avoid empty matches.
- Unit-test your chunker with edge inputs: empty buffer, whitespace-only buffer.
- Wrap match[0] returns with a length check.
When it happens
Trigger: Calling smoothStream({ chunking: myFn }) where myFn(buffer) returns '' (empty string) on a non-null match — e.g. returning buffer.slice(0, 0), a match[0] that is empty, or a function that returns '' instead of null when no chunk boundary is found.
Common situations: Writing a custom chunk detector that uses String.match or exec and forgets to guard against an empty match (e.g. a regex with zero-width alternatives like /\s*/); returning '' as a sentinel for 'no chunk yet' instead of null.
Related errors
- The chunking function must return a prefix of the buffered t
- chunking must be "word", "line", a RegExp, an Intl.Segmenter
- The chunking RegExp must match a non-empty string.
- 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/fec7b4bb782cf49b.
Report an issue: GitHub.