{"record":{"id":"6ae3735aaeac5b79","repo":"mastra-ai/mastra","slug":"reflection-blockafter-this-reflectionconfig-blo","errorCode":null,"errorMessage":"reflection.blockAfter (${this.reflectionConfig.blockAfter}) must be >= reflection.observationTokens (${reflectionThreshold})","messagePattern":"reflection\\.blockAfter \\((.+?)\\) must be >= reflection\\.observationTokens \\((.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/observational-memory.ts","lineNumber":1057,"sourceCode":"          `observation.previousObserverTokens must be false or a finite number >= 0, got ${this.observationConfig.previousObserverTokens}`,\n        );\n      }\n    }\n\n    // Validate reflection bufferActivation (0-1 float range)\n    if (this.reflectionConfig.bufferActivation !== undefined) {\n      if (this.reflectionConfig.bufferActivation <= 0 || this.reflectionConfig.bufferActivation > 1) {\n        throw new Error(\n          `reflection.bufferActivation must be in range (0, 1], got ${this.reflectionConfig.bufferActivation}`,\n        );\n      }\n    }\n\n    // Validate reflection blockAfter\n    if (this.reflectionConfig.blockAfter !== undefined) {\n      const reflectionThreshold = getMaxThreshold(this.reflectionConfig.observationTokens);\n      if (this.reflectionConfig.blockAfter < reflectionThreshold) {\n        throw new Error(\n          `reflection.blockAfter (${this.reflectionConfig.blockAfter}) must be >= reflection.observationTokens (${reflectionThreshold})`,\n        );\n      }\n      if (!this.reflectionConfig.bufferActivation) {\n        throw new Error(\n          `reflection.blockAfter requires reflection.bufferActivation to be set (blockAfter only applies when async reflection is enabled)`,\n        );\n      }\n    }\n  }\n\n  /**\n   * Resolve the effective messageTokens for a record.\n   * Only explicit per-record overrides (stored under `_overrides`) win;\n   * the initial config snapshot written by getOrCreateRecord() is ignored\n   * so that later instance-level changes still take effect.\n   *\n   * Overrides that fall below the instance-level buffering floor","sourceCodeStart":1039,"sourceCodeEnd":1075,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/observational-memory.ts#L1039-L1075","documentation":"When `reflectionConfig.blockAfter` is set, ObservationalMemory checks it against `getMaxThreshold(reflectionConfig.observationTokens)` — the maximum token threshold derived from the observation-token budget. `blockAfter` marks the point at which messages are blocked pending reflection, so it can never legitimately sit below the reflection token threshold. The processor throws at construction when `blockAfter < reflectionThreshold`.","triggerScenarios":"Constructing ObservationalMemory with `reflection: { blockAfter: N, observationTokens: M }` where N < getMaxThreshold(M), e.g. `blockAfter: 1000` with `observationTokens: 2000` (observational-memory.ts:1057).","commonSituations":"Tuning `observationTokens` upward after previously setting `blockAfter` to a now-too-small value; copying a blockAfter from another project with different token budgets; misunderstanding that blockAfter is an absolute token count, not a small message offset.","solutions":["Raise `reflection.blockAfter` so it is >= getMaxThreshold(reflection.observationTokens).","Lower `reflection.observationTokens` so its max threshold falls below the intended blockAfter.","Remove `blockAfter` if you do not need blocking behavior and rely on default reflection flow.","Compute blockAfter programmatically from observationTokens rather than hard-coding it."],"exampleFix":"// before\nreflection: { observationTokens: 2000, blockAfter: 1000 }\n// after\nreflection: { observationTokens: 2000, blockAfter: 4000 }","handlingStrategy":"validation","validationCode":"// using the library's own getMaxThreshold\nconst threshold = getMaxThreshold(config.reflection.observationTokens);\nif (config.reflection.blockAfter < threshold) {\n  config.reflection.blockAfter = threshold;\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive blockAfter from observationTokens programmatically instead of hard-coding.","Re-validate config after any change to observationTokens.","Keep OM reflection settings in one typed config object so related fields change together."],"tags":["configuration","validation","observational-memory"],"backgroundTag":"invalid-config-value","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}