mastra-ai/mastra · error
shareTokenBudget requires async buffering to be disabled (th
Error message
shareTokenBudget requires async buffering to be disabled (this is a temporary limitation). Add observation: { bufferTokens: false } to your config:
observationalMemory: {
shareTokenBudget: true,
observation: { bufferTokens: false },
}
Remove any other async buffering settings (bufferTokens, bufferActivation, blockAfter). What it means
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.
Source
Thrown at packages/memory/src/processors/observational-memory/observational-memory.ts:559
const userExplicitlyConfiguredAsync =
config.observation?.bufferTokens !== undefined ||
config.observation?.bufferActivation !== undefined ||
config.reflection?.bufferActivation !== undefined;
const asyncBufferingDisabled =
config.observation?.bufferTokens === false || (config.scope === 'resource' && !userExplicitlyConfiguredAsync);
// shareTokenBudget is not yet compatible with async buffering (temporary limitation).
// To use shareTokenBudget, users must explicitly disable buffering.
if (isSharedBudget && !asyncBufferingDisabled) {
const common =
`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`;
if (userExplicitlyConfiguredAsync) {
throw new Error(
common + `\nRemove any other async buffering settings (bufferTokens, bufferActivation, blockAfter).`,
);
} else {
throw new Error(
common + `\nAsync buffering is enabled by default — this opt-out is only needed when using shareTokenBudget.`,
);
}
}
const observationActivateAfterIdle = config.observation?.activateAfterIdle ?? config.activateAfterIdle;
const observationActivateAfterIdlePath =
config.observation?.activateAfterIdle !== undefined ? 'observation.activateAfterIdle' : 'activateAfterIdle';
// Resolve observation config with defaults
this.observationConfig = {
model: observationModel,
// When shared budget, store as range: min = base threshold, max = total budget
// This allows messages to expand into unused observation spaceView on GitHub (pinned to 75dd419e61)
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
Example fix
// before
new ObservationalMemory({
model,
shareTokenBudget: true,
observation: { bufferTokens: 2000, bufferActivation: true }
})
// after
new ObservationalMemory({
model,
shareTokenBudget: true,
observation: { bufferTokens: false }
}) Defensive patterns
Strategy: validation
Validate before calling
function assertShareTokenBudgetCompatible(c: ObservationalMemoryConfig): void {
if (!c.shareTokenBudget) return;
const o = c.observation ?? {};
const asyncConfigured =
(o.bufferTokens !== undefined && o.bufferTokens !== false) ||
o.bufferActivation !== undefined || o.blockAfter !== undefined;
if (asyncConfigured || o.bufferTokens !== false) {
throw new Error('shareTokenBudget requires observation: { bufferTokens: false } and no other async buffering settings');
}
} Type guard
function isShareTokenBudgetConfig(c: ObservationalMemoryConfig): boolean {
return !c.shareTokenBudget || c.observation?.bufferTokens === false;
} Try / catch
try {
const mem = new ObservationalMemory(config);
} catch (err) {
if (err instanceof Error && err.message.includes('shareTokenBudget requires async buffering')) {
config.observation = { ...config.observation, bufferTokens: false };
delete (config.observation as any).bufferActivation;
delete (config.observation as any).blockAfter;
} else throw err;
} Prevention
- 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
When it happens
Trigger: new ObservationalMemory({ shareTokenBudget: true, observation: { bufferTokens: true } }) or setting shareTokenBudget with any explicit bufferTokens/bufferActivation/blockAfter values.
Common situations: Enabling token budget sharing on a config that already had async buffering tuned; combining feature flags from different docs examples.
Related errors
- shareTokenBudget requires async buffering to be disabled (th
- Cookie password must be at least 32 characters. Set WORKOS_C
- Factory rule version is required.
- ${label} must be an object.
- Factory rules must be an object.
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/6646abbbf969d598.
Report an issue: GitHub.