{"record":{"id":"8dc96ad4e4613e16","repo":"mastra-ai/mastra","slug":"observation-buffertokens-must-be-0-got-this-o","errorCode":null,"errorMessage":"observation.bufferTokens must be > 0, got ${this.observationConfig.bufferTokens}","messagePattern":"observation\\.bufferTokens must be > 0, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/observational-memory.ts","lineNumber":986,"sourceCode":"   */\n  private validateBufferConfig(): void {\n    // Async buffering is not yet supported with resource scope\n    const hasAsyncBuffering =\n      this.observationConfig.bufferTokens !== undefined ||\n      this.observationConfig.bufferActivation !== undefined ||\n      this.reflectionConfig.bufferActivation !== undefined;\n    if (hasAsyncBuffering && this.scope === 'resource') {\n      throw new Error(\n        `Async buffering is not yet supported with scope: 'resource'. ` +\n          `Use scope: 'thread', or set observation: { bufferTokens: false } to disable async buffering.`,\n      );\n    }\n\n    // Validate observation bufferTokens\n    const observationThreshold = getMaxThreshold(this.observationConfig.messageTokens);\n    if (this.observationConfig.bufferTokens !== undefined) {\n      if (this.observationConfig.bufferTokens <= 0) {\n        throw new Error(`observation.bufferTokens must be > 0, got ${this.observationConfig.bufferTokens}`);\n      }\n      if (this.observationConfig.bufferTokens >= observationThreshold) {\n        throw new Error(\n          `observation.bufferTokens (${this.observationConfig.bufferTokens}) must be less than messageTokens (${observationThreshold})`,\n        );\n      }\n    }\n\n    // Validate observation bufferActivation: (0, 1] for ratio, or >= 1000 for absolute retention tokens\n    if (this.observationConfig.bufferActivation !== undefined) {\n      if (this.observationConfig.bufferActivation <= 0) {\n        throw new Error(`observation.bufferActivation must be > 0, got ${this.observationConfig.bufferActivation}`);\n      }\n      if (this.observationConfig.bufferActivation > 1 && this.observationConfig.bufferActivation < 1000) {\n        throw new Error(\n          `observation.bufferActivation must be <= 1 (ratio) or >= 1000 (absolute token retention), got ${this.observationConfig.bufferActivation}`,\n        );\n      }","sourceCodeStart":968,"sourceCodeEnd":1004,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/observational-memory.ts#L968-L1004","documentation":"The constructor validates that observation.bufferTokens, when provided, is a positive number. A value of 0 or negative would mean the buffer never accumulates anything or is inverted, which is nonsensical, so construction fails immediately with the offending value in the message.","triggerScenarios":"new ObservationalMemory({ observation: { bufferTokens: 0 } }) or any value <= 0 (e.g. -500), typically from computed values like bufferTokens: someLimit - someLimit.","commonSituations":"Deriving bufferTokens from environment variables where the var is unset/0; arithmetic producing 0; typos passing milliseconds or percentages into a token field.","solutions":["Set bufferTokens to a positive integer smaller than your messageTokens threshold (e.g. 1000-4000).","Remove the bufferTokens option entirely to use the default buffering behavior.","If the value comes from config/env, clamp it: Math.max(1, parsedValue)."],"exampleFix":"// before\nnew ObservationalMemory({ observation: { bufferTokens: Number(process.env.BUFFER_TOKENS) } });\n// after\nconst bt = Number(process.env.BUFFER_TOKENS);\nnew ObservationalMemory({ observation: { bufferTokens: Number.isFinite(bt) && bt > 0 ? bt : undefined } });","handlingStrategy":"validation","validationCode":"const bt = Number(process.env.OBS_BUFFER_TOKENS);\nif (bt !== undefined && (!Number.isFinite(bt) || bt <= 0)) {\n  throw new Error(`observation.bufferTokens must be > 0, got ${bt}`);\n}","typeGuard":"function isValidBufferTokens(v: unknown): v is number {\n  return typeof v === 'number' && Number.isFinite(v) && v > 0;\n}","tryCatchPattern":"try {\n  memory = new ObservationalMemory({ observation: { bufferTokens } });\n} catch (e) {\n  if (/bufferTokens must be > 0/.test(e.message)) {\n    memory = new ObservationalMemory({}); // fall back to defaults\n  } else throw e;\n}","preventionTips":["Never feed raw env vars into bufferTokens; parse and clamp first.","Document bufferTokens as a positive integer in your config schema.","Test config construction at startup so failures surface before traffic."],"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"}