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

  1. Return null (not '') from your chunking function when no boundary should be emitted this tick.
  2. Ensure any returned match has at least one character; adjust your regex to require content (use \s+ not \s*, avoid zero-width matches).
  3. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/fec7b4bb782cf49b. Report an issue: GitHub.