{"record":{"id":"6646abbbf969d598","repo":"mastra-ai/mastra","slug":"sharetokenbudget-requires-async-buffering-to-be-di","errorCode":null,"errorMessage":"shareTokenBudget requires async buffering to be disabled (this is a temporary limitation). Add observation: { bufferTokens: false } to your config:\n\n  observationalMemory: {\n    shareTokenBudget: true,\n    observation: { bufferTokens: false },\n  }\n\nRemove any other async buffering settings (bufferTokens, bufferActivation, blockAfter).","messagePattern":"shareTokenBudget requires async buffering to be disabled \\(this is a temporary limitation\\)\\. Add observation: (.+?) to your config:\n\n  observationalMemory: (.+?),\n  \\}\n\nRemove any other async buffering settings \\(bufferTokens, bufferActivation, blockAfter\\)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/memory/src/processors/observational-memory/observational-memory.ts","lineNumber":559,"sourceCode":"    const userExplicitlyConfiguredAsync =\n      config.observation?.bufferTokens !== undefined ||\n      config.observation?.bufferActivation !== undefined ||\n      config.reflection?.bufferActivation !== undefined;\n    const asyncBufferingDisabled =\n      config.observation?.bufferTokens === false || (config.scope === 'resource' && !userExplicitlyConfiguredAsync);\n\n    // shareTokenBudget is not yet compatible with async buffering (temporary limitation).\n    // To use shareTokenBudget, users must explicitly disable buffering.\n    if (isSharedBudget && !asyncBufferingDisabled) {\n      const common =\n        `shareTokenBudget requires async buffering to be disabled (this is a temporary limitation). ` +\n        `Add observation: { bufferTokens: false } to your config:\\n\\n` +\n        `  observationalMemory: {\\n` +\n        `    shareTokenBudget: true,\\n` +\n        `    observation: { bufferTokens: false },\\n` +\n        `  }\\n`;\n      if (userExplicitlyConfiguredAsync) {\n        throw new Error(\n          common + `\\nRemove any other async buffering settings (bufferTokens, bufferActivation, blockAfter).`,\n        );\n      } else {\n        throw new Error(\n          common + `\\nAsync buffering is enabled by default — this opt-out is only needed when using shareTokenBudget.`,\n        );\n      }\n    }\n\n    const observationActivateAfterIdle = config.observation?.activateAfterIdle ?? config.activateAfterIdle;\n    const observationActivateAfterIdlePath =\n      config.observation?.activateAfterIdle !== undefined ? 'observation.activateAfterIdle' : 'activateAfterIdle';\n\n    // Resolve observation config with defaults\n    this.observationConfig = {\n      model: observationModel,\n      // When shared budget, store as range: min = base threshold, max = total budget\n      // This allows messages to expand into unused observation space","sourceCodeStart":541,"sourceCodeEnd":577,"githubUrl":"https://github.com/mastra-ai/mastra/blob/75dd419e613fe9c39f846ffc500716141b74fda6/packages/memory/src/processors/observational-memory/observational-memory.ts#L541-L577","documentation":"shareTokenBudget is temporarily incompatible with async observation buffering. When the user explicitly configured async buffering options (bufferTokens, bufferActivation, or blockAfter) together with shareTokenBudget, the constructor throws with instructions to disable buffering.","triggerScenarios":"new ObservationalMemory({ shareTokenBudget: true, observation: { bufferTokens: true } }) or setting shareTokenBudget with any explicit bufferTokens/bufferActivation/blockAfter values.","commonSituations":"Enabling token budget sharing on a config that already had async buffering tuned; combining feature flags from different docs examples.","solutions":["Add observation: { bufferTokens: false } and remove bufferTokens, bufferActivation, and blockAfter settings","Remove shareTokenBudget: true if async buffering is more important for your workload","Wait for/upgrade to a version where the limitation is lifted"],"exampleFix":"// before\nnew ObservationalMemory({\n  model,\n  shareTokenBudget: true,\n  observation: { bufferTokens: 2000, bufferActivation: true }\n})\n// after\nnew ObservationalMemory({\n  model,\n  shareTokenBudget: true,\n  observation: { bufferTokens: false }\n})","handlingStrategy":"validation","validationCode":"function assertShareTokenBudgetCompatible(c: ObservationalMemoryConfig): void {\n  if (!c.shareTokenBudget) return;\n  const o = c.observation ?? {};\n  const asyncConfigured =\n    (o.bufferTokens !== undefined && o.bufferTokens !== false) ||\n    o.bufferActivation !== undefined || o.blockAfter !== undefined;\n  if (asyncConfigured || o.bufferTokens !== false) {\n    throw new Error('shareTokenBudget requires observation: { bufferTokens: false } and no other async buffering settings');\n  }\n}","typeGuard":"function isShareTokenBudgetConfig(c: ObservationalMemoryConfig): boolean {\n  return !c.shareTokenBudget || c.observation?.bufferTokens === false;\n}","tryCatchPattern":"try {\n  const mem = new ObservationalMemory(config);\n} catch (err) {\n  if (err instanceof Error && err.message.includes('shareTokenBudget requires async buffering')) {\n    config.observation = { ...config.observation, bufferTokens: false };\n    delete (config.observation as any).bufferActivation;\n    delete (config.observation as any).blockAfter;\n  } else throw err;\n}","preventionTips":["Whenever shareTokenBudget is enabled, set observation: { bufferTokens: false } in the same place","Don't copy bufferTokens/bufferActivation/blockAfter tuning into shareTokenBudget configs","Comment the temporary limitation at the config site so future edits keep the invariant"],"tags":["config","validation","incompatible-options","tokens"],"backgroundTag":"conflicting-config-options","analyzedSha":"75dd419e613fe9c39f846ffc500716141b74fda6","analyzedAt":"2026-08-30T00:15:31.844Z","schemaVersion":2},"datasetVersion":"2026-08-30T03:17:51.788Z"}