mastra-ai/mastra · error · Error
Observational memory record not found: ${currentRecord.id}
Error message
Observational memory record not found: ${currentRecord.id} What it means
swapBufferedReflectionToActive promotes a buffered reflection into the active observations by creating a new reflection generation. It first resolves the record by currentRecord.id and throws this error when the record no longer exists in the in-memory store. This prevents creating a bogus generation from a deleted or unknown record.
Source
Thrown at packages/core/src/storage/domains/memory/inmemory.ts:1157
const { id, reflection, tokenCount, inputTokenCount, reflectedObservationLineCount } = input;
const record = this.findObservationalMemoryRecordById(id);
if (!record) {
throw new Error(`Observational memory record not found: ${id}`);
}
const existing = record.bufferedReflection || '';
record.bufferedReflection = existing ? `${existing}\n\n${reflection}` : reflection;
record.bufferedReflectionTokens = (record.bufferedReflectionTokens || 0) + tokenCount;
record.bufferedReflectionInputTokens = (record.bufferedReflectionInputTokens || 0) + inputTokenCount;
record.reflectedObservationLineCount = reflectedObservationLineCount;
record.updatedAt = new Date();
}
async swapBufferedReflectionToActive(input: SwapBufferedReflectionToActiveInput): Promise<ObservationalMemoryRecord> {
const { currentRecord } = input;
const record = this.findObservationalMemoryRecordById(currentRecord.id);
if (!record) {
throw new Error(`Observational memory record not found: ${currentRecord.id}`);
}
if (!record.bufferedReflection) {
throw new Error('No buffered reflection to swap');
}
const bufferedReflection = record.bufferedReflection;
const reflectedLineCount = record.reflectedObservationLineCount ?? 0;
// Split current activeObservations by the boundary line count.
// Lines 0..reflectedLineCount were reflected on → replaced by bufferedReflection.
// Lines after reflectedLineCount were added after reflection started → kept as-is.
const currentObservations = record.activeObservations ?? '';
const allLines = currentObservations.split('\n');
const unreflectedLines = allLines.slice(reflectedLineCount);
const unreflectedContent = unreflectedLines.join('\n').trim();
// New activeObservations = bufferedReflection + unreflected observationsView on GitHub (pinned to 75dd419e61)
Solutions
- Re-fetch the latest observational memory record for the thread/resource before swapping instead of reusing a stale currentRecord object.
- Avoid calling clearObservationalMemory while a reflection swap is pending.
- Use a persistent storage provider if records must survive process restarts.
- Wrap the call in try/catch and fall back to re-initializing observational memory for the thread.
Example fix
// before
await memory.swapBufferedReflectionToActive({ currentRecord: staleRecord, tokenCount });
// after
const current = await memory.getLatestObservationalMemoryRecord(threadId, resourceId);
if (!current) return;
await memory.swapBufferedReflectionToActive({ currentRecord: current, tokenCount }); Defensive patterns
Strategy: try-catch
Validate before calling
const current = await memory.getLatestObservationalMemoryRecord(threadId, resourceId);
if (!current || current.id !== currentRecord.id) throw new Error('Stale observational memory record'); Type guard
function isCurrentRecord(r: ObservationalMemoryRecord | undefined, id: string): r is ObservationalMemoryRecord {
return r !== undefined && r.id === id;
} Try / catch
try {
const next = await memory.swapBufferedReflectionToActive({ currentRecord, tokenCount });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Observational memory record not found')) {
currentRecord = await memory.getLatestObservationalMemoryRecord(threadId, resourceId);
} else throw e;
} Prevention
- Re-fetch the record immediately before swapping.
- Make reflection swap steps idempotent against retries.
- Don't clear observational memory mid-reflection.
- Use durable storage for long-running reflection jobs.
When it happens
Trigger: Calling swapBufferedReflectionToActive({ currentRecord, tokenCount }) where currentRecord.id is not present in the store — typically because clearObservationalMemory ran, the process restarted, or the record id came from another storage instance/provider.
Common situations: Long-running reflection jobs that outlive an in-memory storage reset; passing a serialized record from a previous session; switching storage providers without migrating record ids.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- AGENT_NETWORK_OBSERVATIONAL_MEMORY_UNSUPPORTED
- No buffered reflection to swap
- Observational memory record not found: ${input.id}
- Observational memory is enabled but the installed version of
- Observational memory async buffering is enabled by default b
AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30).
Data as JSON: /api/errors/1bad76fb16361076.
Report an issue: GitHub.