mastra-ai/mastra · error

observation.previousObserverTokens must be false or a finite

Error message

observation.previousObserverTokens must be false or a finite number >= 0, got ${this.observationConfig.previousObserverTokens}

What it means

observation.previousObserverTokens controls how many tokens from prior observer output are carried into the next observation context. It must be either false (feature disabled) or a finite non-negative number; NaN, Infinity, negative values, or other non-numeric junk are rejected at construction so a broken value can't corrupt observer context assembly.

Source

Thrown at packages/memory/src/processors/observational-memory/observational-memory.ts:1038

        );
      }
      if (!this.observationConfig.bufferTokens) {
        throw new Error(
          `observation.blockAfter requires observation.bufferTokens to be set (blockAfter only applies when async buffering is enabled)`,
        );
      }
    }

    // Validate observer context optimization options
    if (
      this.observationConfig.previousObserverTokens !== undefined &&
      this.observationConfig.previousObserverTokens !== false
    ) {
      if (
        !Number.isFinite(this.observationConfig.previousObserverTokens) ||
        this.observationConfig.previousObserverTokens < 0
      ) {
        throw new Error(
          `observation.previousObserverTokens must be false or a finite number >= 0, got ${this.observationConfig.previousObserverTokens}`,
        );
      }
    }

    // Validate reflection bufferActivation (0-1 float range)
    if (this.reflectionConfig.bufferActivation !== undefined) {
      if (this.reflectionConfig.bufferActivation <= 0 || this.reflectionConfig.bufferActivation > 1) {
        throw new Error(
          `reflection.bufferActivation must be in range (0, 1], got ${this.reflectionConfig.bufferActivation}`,
        );
      }
    }

    // Validate reflection blockAfter
    if (this.reflectionConfig.blockAfter !== undefined) {
      const reflectionThreshold = getMaxThreshold(this.reflectionConfig.observationTokens);
      if (this.reflectionConfig.blockAfter < reflectionThreshold) {

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Set previousObserverTokens to a finite number >= 0 (e.g. 2000).
  2. Use false to disable carrying previous observer output, instead of -1 or 0-as-disabled.
  3. Validate/parse config values: Number.isFinite(v) && v >= 0 before passing them in.

Example fix

// before
new ObservationalMemory({ observation: { previousObserverTokens: -1 } });
// after
new ObservationalMemory({ observation: { previousObserverTokens: false } }); // or 2000
Defensive patterns

Strategy: validation

Validate before calling

const pot = observationConfig.previousObserverTokens;
if (pot !== undefined && pot !== false && (!Number.isFinite(pot) || pot < 0)) {
  throw new Error(`previousObserverTokens must be false or a finite number >= 0, got ${pot}`);
}

Type guard

function isValidPreviousObserverTokens(v: unknown): v is number | false {
  return v === false || (typeof v === 'number' && Number.isFinite(v) && v >= 0);
}

Prevention

When it happens

Trigger: new ObservationalMemory({ observation: { previousObserverTokens: -100 } }), previousObserverTokens: Infinity/NaN (often from division or parseInt of a bad string), or a non-number like a string '2000' reaching the check.

Common situations: Parsing the value from env/config without validation (parseInt returns NaN); computing a limit with division by zero producing Infinity; using -1 to mean 'unlimited' when the API expects false for disabled.

Understand the failure class

Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.

Related errors


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