mastra-ai/mastra · error

RegexFilterProcessor streamCarryoverSize must be a positive

Error message

RegexFilterProcessor streamCarryoverSize must be a positive safe integer

What it means

RegexFilterProcessor keeps a carryover buffer when filtering streamed text so matches spanning chunk boundaries are handled correctly. The `streamCarryoverSize` option must be a positive safe integer (>= 1); anything else (0, negative, NaN, Infinity, non-integer) makes the buffer logic invalid, so the constructor throws. The default is `STREAM_CARRYOVER_SIZE`.

Source

Thrown at packages/core/src/processors/processors/regex-filter.ts:331

   * through the same callback, driven by the processor runner when it catches
   * the TripWire.
   */
  public onViolation?: (violation: ProcessorViolation) => void | Promise<void>;

  constructor(options: RegexFilterOptions) {
    const presetRules = (options.presets ?? []).flatMap(preset => PRESET_MAP[preset] ?? []);
    this.rules = [...presetRules, ...(options.rules ?? [])];

    if (this.rules.length === 0) {
      throw new Error('RegexFilterProcessor requires at least one rule or preset');
    }

    this.strategy = options.strategy ?? 'block';
    this.phase = options.phase ?? 'all';
    this.includeRedactedValues = options.includeRedactedValues ?? false;
    this.streamCarryoverSize = options.streamCarryoverSize ?? STREAM_CARRYOVER_SIZE;
    if (!Number.isSafeInteger(this.streamCarryoverSize) || this.streamCarryoverSize < 1) {
      throw new Error('RegexFilterProcessor streamCarryoverSize must be a positive safe integer');
    }
  }

  /**
   * Run every rule over the text and collect all matches, grouped by rule in
   * declaration order. Matches may overlap; callers that rewrite text must
   * de-overlap them first.
   */
  private collectMatches(text: string): RuleMatch[] {
    const matches: RuleMatch[] = [];
    for (const rule of this.rules) {
      const regex = compilePattern(rule);
      let m: RegExpExecArray | null;
      while ((m = regex.exec(text)) !== null) {
        matches.push({ rule, start: m.index, end: m.index + m[0].length });
        if (!regex.global) break;
        if (m[0].length === 0) {
          regex.lastIndex++;

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set `streamCarryoverSize` to a positive whole number (e.g. 256 or 1024).
  2. Omit the option entirely to use the built-in default `STREAM_CARRYOVER_SIZE`.
  3. Parse env/config values with `Number.parseInt`/`Number` and validate with `Number.isSafeInteger(v) && v >= 1` before passing.
  4. Use `Math.max(1, Math.floor(value))` to sanitize computed values.

Example fix

// before
new RegexFilterProcessor({ rules, streamCarryoverSize: Number(process.env.CARRYOVER) });
// after
const size = Number.parseInt(process.env.CARRYOVER ?? '', 10);
new RegexFilterProcessor({ rules, streamCarryoverSize: Number.isSafeInteger(size) && size >= 1 ? size : undefined });
Defensive patterns

Strategy: validation

Validate before calling

const size = options.streamCarryoverSize;
if (size !== undefined && !(Number.isSafeInteger(size) && size >= 1)) {
  throw new TypeError(`streamCarryoverSize must be a positive safe integer, got ${size}`);
}

Type guard

function isValidCarryoverSize(v: unknown): v is number {
  return typeof v === 'number' && Number.isSafeInteger(v) && v >= 1;
}

Try / catch

try {
  return new RegexFilterProcessor(opts);
} catch (e) {
  if (e.message.includes('streamCarryoverSize')) {
    return new RegexFilterProcessor({ ...opts, streamCarryoverSize: undefined }); // fall back to default
  }
  throw e;
}

Prevention

When it happens

Trigger: Passing `streamCarryoverSize: 0`, a negative number, a float like `2.5`, `Infinity`, `NaN`, or a string in `new RegexFilterProcessor({ streamCarryoverSize: ... })`. `Number.isSafeInteger` fails for all non-integer/infinite values; `< 1` catches 0 and negatives.

Common situations: Reading the value from a config file or env var without parsing (`'1000'` as string is not a safe integer), computing it with division that yields a fraction, or assuming 0 means 'unlimited'.

Understand the failure class

Background: "must be positive", "Invalid value": how libraries reject invalid parameter values (ValueError, ArgumentError, INVALID_PARAMETER_VALUE) — this error's family across 28 libraries.

Related errors


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