{"record":{"id":"02f97f10da8e49f9","repo":"thedotmack/claude-mem","slug":"auto-reprime-failed-for-corpus-corpus-name","errorCode":null,"errorMessage":"Auto-reprime failed for corpus \"${corpus.name}\"","messagePattern":"Auto-reprime failed for corpus \"(.+?)\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/services/worker/knowledge/KnowledgeAgent.ts","lineNumber":109,"sourceCode":"      if (result.session_id !== corpus.session_id) {\n        corpus.session_id = result.session_id;\n        this.corpusStore.write(corpus);\n      }\n      return result;\n    } catch (error) {\n      if (!this.isSessionResumeError(error)) {\n        if (error instanceof Error) {\n          logger.error('WORKER', `Query failed for corpus \"${corpus.name}\"`, {}, error);\n        } else {\n          logger.error('WORKER', `Query failed for corpus \"${corpus.name}\" (non-Error thrown)`, { thrownValue: String(error) });\n        }\n        throw error;\n      }\n      logger.info('WORKER', `Session expired for corpus \"${corpus.name}\", auto-repriming...`);\n      await this.prime(corpus);\n      const refreshedCorpus = this.corpusStore.read(corpus.name);\n      if (!refreshedCorpus || !refreshedCorpus.session_id) {\n        throw new Error(`Auto-reprime failed for corpus \"${corpus.name}\"`);\n      }\n      const result = await this.executeQuery(refreshedCorpus, question);\n      if (result.session_id !== refreshedCorpus.session_id) {\n        refreshedCorpus.session_id = result.session_id;\n        this.corpusStore.write(refreshedCorpus);\n      }\n      return result;\n    }\n  }\n\n  async reprime(corpus: CorpusFile): Promise<string> {\n    corpus.session_id = null;  \n    return this.prime(corpus);\n  }\n\n  private isSessionResumeError(error: unknown): boolean {\n    const message = error instanceof Error ? error.message : String(error);\n    return /session|resume|expired|invalid.*session|not found/i.test(message);","sourceCodeStart":91,"sourceCodeEnd":127,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/worker/knowledge/KnowledgeAgent.ts#L91-L127","documentation":"When a query fails because the corpus session expired, KnowledgeAgent.query() auto-reprimes and then re-checks the stored corpus; if the reprimed corpus still lacks a session_id, it throws this error. It indicates the recovery path itself failed — the prime() call did not produce (or persist) a fresh session_id.","triggerScenarios":"Auto-reprime path: prime() ran but returned without capturing a session_id (see error 155), the corpusStore.write() failed so the re-read has no session_id, or the re-read returned null because the corpus file was deleted between operations.","commonSituations":"Persistent backend problem during reprime (LLM down, quota exhausted); read-only filesystem preventing corpusStore.write from persisting the new session; concurrent process overwriting the corpus file mid-reprime; SDK response-shape change breaking prime's session capture.","solutions":["Fix the underlying cause of the failed prime — check prime() logs and the Claude backend availability","Verify the corpora directory is writable so corpusStore.write can persist the new session_id","Manually run prime(corpus) and confirm the stored JSON now has session_id, then retry the query","Check for concurrent processes rewriting the corpus file; serialize access or use file locking"],"exampleFix":"// before\nconst refreshedCorpus = this.corpusStore.read(corpus.name);\nif (!refreshedCorpus || !refreshedCorpus.session_id) {\n  throw new Error(`Auto-reprime failed for corpus \"${corpus.name}\"`);\n}\n// after\nconst refreshedCorpus = this.corpusStore.read(corpus.name);\nif (!refreshedCorpus || !refreshedCorpus.session_id) {\n  logger.error('WORKER', 'auto-reprime produced no session', { corpus: corpus.name });\n  await new Promise(r => setTimeout(r, 1000)); // brief backoff\n  await this.prime(corpus);\n  // then re-read and re-check before giving up\n}","handlingStrategy":"retry","validationCode":"const corpus = corpusStore.read(name);\nconst readyToQuery = !!corpus && typeof corpus.session_id === 'string' && corpus.session_id.length > 0;\nif (!readyToQuery) {\n  await agent.prime(corpus);\n  // re-read and confirm session_id exists before querying\n}","typeGuard":null,"tryCatchPattern":"try {\n  return await agent.query(corpus, question);\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Auto-reprime failed')) {\n    // recovery path failed: check filesystem writability + backend health, then retry once manually\n    await agent.prime(corpus);\n    const fresh = corpusStore.read(corpus.name);\n    if (fresh?.session_id) return agent.query(fresh, question);\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Ensure the corpora directory is writable by the worker process","Avoid concurrent writers to the same corpus file (lock or single-writer design)","Monitor prime() success rates to catch backend outages before queries pile up","Pin SDK versions so prime's session_id capture doesn't break silently"],"tags":["retry","session-expired","knowledge-base"],"backgroundTag":"session-expired","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"}