{"record":{"id":"0f1ea5b456b9eb90","repo":"thedotmack/claude-mem","slug":"cannot-process-observations-memorysessionid-not-y","errorCode":null,"errorMessage":"Cannot process observations: memorySessionId not yet captured. This session may need to be reinitialized.","messagePattern":"Cannot process observations: memorySessionId not yet captured\\. This session may need to be reinitialized\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/worker/OpenAICompatibleProvider.ts","lineNumber":275,"sourceCode":"    // that never happened. Keep the turn so role alternation holds, but never\n    // hand it to the storage path.\n    session.conversationHistory.push({ role: 'assistant', content: initResponse.content || '' });\n  }\n\n  private async processObservationMessage(\n    session: ActiveSession,\n    message: { prompt_number?: number; tool_name?: string; tool_input?: unknown; tool_response?: unknown; cwd?: string },\n    worker: WorkerRef | undefined,\n    config: TConfig,\n    originalTimestamp: number | null,\n    lastCwd: string | undefined\n  ): Promise<void> {\n    if (message.prompt_number !== undefined) {\n      session.lastPromptNumber = message.prompt_number;\n    }\n\n    if (!session.memorySessionId) {\n      throw new Error('Cannot process observations: memorySessionId not yet captured. This session may need to be reinitialized.');\n    }\n\n    // Retire a full generation BEFORE sending, so the request that would cross\n    // the ceiling is never paid for. The batch is preserved and drained by the\n    // fresh generation the next ingest starts (#3800).\n    if (shouldRecycleConversation(session.conversationHistory, this.conversationMaxChars())) {\n      await recycleObserverConversation(\n        session,\n        this.sessionManager,\n        worker,\n        'budget',\n        `conversation reached ${conversationChars(session.conversationHistory)} chars`,\n      );\n      return;\n    }\n\n    // An oversized payload is condensed by a bounded model pass before the\n    // prompt is built, so the observation carries a summary of the whole field","sourceCodeStart":257,"sourceCodeEnd":293,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/worker/OpenAICompatibleProvider.ts#L257-L293","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait processObservationMessage(message, session);\n// after\nif (!session.memorySessionId) {\n  session.memorySessionId = await createMemorySession(session); // re-init first\n}\nawait processObservationMessage(message, session);","handlingStrategy":"try-catch","validationCode":"if (!session.memorySessionId) await initializeMemorySession(session);","typeGuard":null,"tryCatchPattern":"try { await provider.runMessageLoop(session, msg); } catch (e) { if (e.message.includes('memorySessionId not yet captured')) { await reinitializeSession(session); } }","preventionTips":["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."],"tags":["session","initialization","invalid-state"],"backgroundTag":"invalid-state-transition","analyzedSha":"d8bc9755e74915e5c3b999181e10a67c889bce2a","analyzedAt":"2026-09-17T16:40:26.182Z","contentChangedAt":"2026-09-17T16:40:26.182Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}