{"record":{"id":"c6cdf269501d5634","repo":"mastra-ai/mastra","slug":"observation-blockafter-requires-observation-buffer","errorCode":null,"errorMessage":"observation.blockAfter requires observation.bufferTokens to be set (blockAfter only applies when async buffering is enabled)","messagePattern":"observation\\.blockAfter requires observation\\.bufferTokens to be set \\(blockAfter only applies when async buffering is enabled\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/observational-memory.ts","lineNumber":1023,"sourceCode":"      if (\n        this.observationConfig.bufferActivation >= 1000 &&\n        this.observationConfig.bufferActivation >= observationThreshold\n      ) {\n        throw new Error(\n          `observation.bufferActivation as absolute retention (${this.observationConfig.bufferActivation}) must be less than messageTokens (${observationThreshold})`,\n        );\n      }\n    }\n\n    // Validate observation blockAfter\n    if (this.observationConfig.blockAfter !== undefined) {\n      if (this.observationConfig.blockAfter < observationThreshold) {\n        throw new Error(\n          `observation.blockAfter (${this.observationConfig.blockAfter}) must be >= messageTokens (${observationThreshold})`,\n        );\n      }\n      if (!this.observationConfig.bufferTokens) {\n        throw new Error(\n          `observation.blockAfter requires observation.bufferTokens to be set (blockAfter only applies when async buffering is enabled)`,\n        );\n      }\n    }\n\n    // Validate observer context optimization options\n    if (\n      this.observationConfig.previousObserverTokens !== undefined &&\n      this.observationConfig.previousObserverTokens !== false\n    ) {\n      if (\n        !Number.isFinite(this.observationConfig.previousObserverTokens) ||\n        this.observationConfig.previousObserverTokens < 0\n      ) {\n        throw new Error(\n          `observation.previousObserverTokens must be false or a finite number >= 0, got ${this.observationConfig.previousObserverTokens}`,\n        );\n      }","sourceCodeStart":1005,"sourceCodeEnd":1041,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/observational-memory.ts#L1005-L1041","documentation":"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.","triggerScenarios":"new ObservationalMemory({ observation: { messageTokens: 4000, blockAfter: 8000 } }) with no bufferTokens; or bufferTokens: false combined with blockAfter.","commonSituations":"Copying a buffered config and removing bufferTokens for sync mode while keeping blockAfter; enabling blockAfter expecting it to work with default (sync) settings.","solutions":["Add observation.bufferTokens (a positive value < messageTokens) to enable async buffering.","Remove blockAfter if you intend to run synchronous processing.","Note that bufferTokens: false explicitly disables buffering, which also triggers this error — drop blockAfter in that case."],"exampleFix":"// before\nnew ObservationalMemory({ observation: { messageTokens: 4000, blockAfter: 8000 } });\n// after\nnew ObservationalMemory({ observation: { messageTokens: 4000, bufferTokens: 1000, blockAfter: 8000 } });","handlingStrategy":"validation","validationCode":"if (observationConfig.blockAfter !== undefined && !observationConfig.bufferTokens) {\n  throw new Error('observation.blockAfter requires observation.bufferTokens to be set');\n}","typeGuard":null,"tryCatchPattern":"try {\n  memory = new ObservationalMemory(cfg);\n} catch (e) {\n  if (e.message.includes('blockAfter requires observation.bufferTokens')) {\n    memory = new ObservationalMemory({ ...cfg, observation: { ...cfg.observation, blockAfter: undefined } });\n  } else throw e;\n}","preventionTips":["Enable bufferTokens whenever you use blockAfter.","Drop blockAfter when migrating to synchronous processing.","Keep blocking-related options grouped in one config builder function."],"tags":["configuration","validation","observational-memory"],"backgroundTag":"incompatible-configuration","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}