thedotmack/claude-mem · error · Error
Cannot process observations: memorySessionId not yet…
Error message
Cannot process observations: memorySessionId not yet captured. This session may need to be reinitialized.
What it means
OpenAICompatibleProvider.processObservationMessage requires session.memorySessionId to be set before it can persist observations, because observations must attach to a memory session record. If ingest has not yet captured the session id (e.g. session creation response never arrived), it throws and asks the user to reinitialize the session.
Solutions
- Reinitialize the session so a new memorySessionId is captured, then resend.
- Check logs/network for a failed session-creation API call and fix that root cause.
- Ensure observation messages are only sent after the session-created acknowledgment.
- Restart the worker/agent session if the id was lost mid-run.
Example fix
// before
await processObservationMessage(message, session);
// after
if (!session.memorySessionId) {
session.memorySessionId = await createMemorySession(session); // re-init first
}
await processObservationMessage(message, session); Defensive patterns
Strategy: try-catch
Validate before calling
if (!session.memorySessionId) await initializeMemorySession(session);
Try / catch
try { await provider.runMessageLoop(session, msg); } catch (e) { if (e.message.includes('memorySessionId not yet captured')) { await reinitializeSession(session); } } Prevention
- Always complete the session-create handshake before ingesting observations.
- Persist memorySessionId so restarts do not lose it.
- Handle session-creation API failures explicitly instead of continuing the loop.
When it happens
Trigger: A message with observations arrives in runMessageLoop while session.memorySessionId is still falsy — the session-start handshake failed, the create-session response was lost, or observations raced ahead of session initialization.
Common situations: Network/API failure during session creation; worker restarted mid-session losing the captured id; provider sending observation messages before the first session acknowledgment; bug in session init ordering.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot process summary: memorySessionId not yet captured…
- cloud sync must be configured before queueDelete
- Context requested before initialization complete, returning…
- Dependency preflight found degraded optional setup
- Failed to capture session_id while priming corpus
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/0f1ea5b456b9eb90.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/worker/OpenAICompatibleProvider.ts:275
// that never happened. Keep the turn so role alternation holds, but never
// hand it to the storage path.
session.conversationHistory.push({ role: 'assistant', content: initResponse.content || '' });
}
private async processObservationMessage(
session: ActiveSession,
message: { prompt_number?: number; tool_name?: string; tool_input?: unknown; tool_response?: unknown; cwd?: string },
worker: WorkerRef | undefined,
config: TConfig,
originalTimestamp: number | null,
lastCwd: string | undefined
): Promise<void> {
if (message.prompt_number !== undefined) {
session.lastPromptNumber = message.prompt_number;
}
if (!session.memorySessionId) {
throw new Error('Cannot process observations: memorySessionId not yet captured. This session may need to be reinitialized.');
}
// Retire a full generation BEFORE sending, so the request that would cross
// the ceiling is never paid for. The batch is preserved and drained by the
// fresh generation the next ingest starts (#3800).
if (shouldRecycleConversation(session.conversationHistory, this.conversationMaxChars())) {
await recycleObserverConversation(
session,
this.sessionManager,
worker,
'budget',
`conversation reached ${conversationChars(session.conversationHistory)} chars`,
);
return;
}
// An oversized payload is condensed by a bounded model pass before the
// prompt is built, so the observation carries a summary of the whole fieldView on GitHub (pinned to d8bc9755e7)