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 observations

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Re-fetch the latest observational memory record for the thread/resource before swapping instead of reusing a stale currentRecord object.
  2. Avoid calling clearObservationalMemory while a reflection swap is pending.
  3. Use a persistent storage provider if records must survive process restarts.
  4. 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

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


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/1bad76fb16361076. Report an issue: GitHub.