mastra-ai/mastra · error

observation.blockAfter requires observation.bufferTokens to

Error message

observation.blockAfter requires observation.bufferTokens to be set (blockAfter only applies when async buffering is enabled)

What it means

blockAfter only takes effect when async buffering is enabled via observation.bufferTokens; in synchronous mode every message batch is processed inline so there is no buffer for blockAfter to gate. The constructor rejects blockAfter without bufferTokens rather than silently ignoring it.

Source

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

      if (
        this.observationConfig.bufferActivation >= 1000 &&
        this.observationConfig.bufferActivation >= observationThreshold
      ) {
        throw new Error(
          `observation.bufferActivation as absolute retention (${this.observationConfig.bufferActivation}) must be less than messageTokens (${observationThreshold})`,
        );
      }
    }

    // Validate observation blockAfter
    if (this.observationConfig.blockAfter !== undefined) {
      if (this.observationConfig.blockAfter < observationThreshold) {
        throw new Error(
          `observation.blockAfter (${this.observationConfig.blockAfter}) must be >= messageTokens (${observationThreshold})`,
        );
      }
      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}`,
        );
      }

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Add observation.bufferTokens (a positive value < messageTokens) to enable async buffering.
  2. Remove blockAfter if you intend to run synchronous processing.
  3. Note that bufferTokens: false explicitly disables buffering, which also triggers this error — drop blockAfter in that case.

Example fix

// before
new ObservationalMemory({ observation: { messageTokens: 4000, blockAfter: 8000 } });
// after
new ObservationalMemory({ observation: { messageTokens: 4000, bufferTokens: 1000, blockAfter: 8000 } });
Defensive patterns

Strategy: validation

Validate before calling

if (observationConfig.blockAfter !== undefined && !observationConfig.bufferTokens) {
  throw new Error('observation.blockAfter requires observation.bufferTokens to be set');
}

Try / catch

try {
  memory = new ObservationalMemory(cfg);
} catch (e) {
  if (e.message.includes('blockAfter requires observation.bufferTokens')) {
    memory = new ObservationalMemory({ ...cfg, observation: { ...cfg.observation, blockAfter: undefined } });
  } else throw e;
}

Prevention

When it happens

Trigger: new ObservationalMemory({ observation: { messageTokens: 4000, blockAfter: 8000 } }) with no bufferTokens; or bufferTokens: false combined with blockAfter.

Common situations: Copying a buffered config and removing bufferTokens for sync mode while keeping blockAfter; enabling blockAfter expecting it to work with default (sync) settings.

Related errors


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