thedotmack/claude-mem · error · Error
Corpus " " has no session — call prime first
Error message
Corpus "${corpus.name}" has no session — call prime first What it means
KnowledgeAgent.query() requires the corpus to have been primed: corpus.session_id must be set, otherwise it throws. The session_id ties queries to an existing Claude conversation that already ingested the corpus, so querying without one is an invalid state, not a retryable failure.
Solutions
- Call agent.prime(corpus) once before the first query to establish the session
- Reload the corpus via corpusStore.read() to pick up a session_id written by another process
- If the file legitimately has no session_id, prime it rather than hand-editing the JSON
- Automate priming in your pipeline so query always follows a successful prime
Example fix
// before
const corpus = corpusStore.read('docs');
const answer = await agent.query(corpus, 'what changed?'); // throws
// after
let corpus = corpusStore.read('docs');
if (!corpus.session_id) {
await agent.prime(corpus);
corpus = corpusStore.read('docs');
}
const answer = await agent.query(corpus, 'what changed?'); Defensive patterns
Strategy: validation
Validate before calling
function isPrimed(corpus: { session_id?: string | null }): corpus is typeof corpus & { session_id: string } {
return typeof corpus.session_id === 'string' && corpus.session_id.length > 0;
}
// usage
if (!isPrimed(corpus)) await agent.prime(corpus); Type guard
function hasSession(c: { session_id?: string | null }): c is typeof c & { session_id: string } {
return typeof c.session_id === 'string' && c.session_id.length > 0;
} Try / catch
try {
return await agent.query(corpus, question);
} catch (err) {
if (err instanceof Error && err.message.includes('has no session')) {
await agent.prime(corpus);
const fresh = corpusStore.read(corpus.name);
return agent.query(fresh, question);
}
throw err;
} Prevention
- Always prime a new corpus before its first query — encode this in your pipeline
- Never hand-edit corpus JSON in ways that can clear session_id
- Restore corpus files together with their primed state, or re-prime after restore
- Reload corpora from disk after external processes may have primed them
When it happens
Trigger: Calling query() on a freshly loaded CorpusFile whose session_id was never written (prime never ran), on a corpus file created by another tool without priming, or on a hand-edited JSON corpus file where session_id was removed.
Common situations: Deploying a new corpus file and immediately running queries without a prime step; restoring corpus JSON from backup where session_id was null; a previous prime crashed (see error 155) leaving the file without a session; stale in-memory CorpusFile object.
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
- Auto-reprime failed for corpus
- Cannot process summary: memorySessionId not yet captured…
- chroma-mcp connection cancelled during shutdown
- cloud sync must be configured before queueDelete
- Failed to capture session_id while priming corpus
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/3a3ad230abcceb51.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/worker/knowledge/KnowledgeAgent.ts:86
}
} else {
throw error;
}
}
if (!sessionId) {
throw new Error(`Failed to capture session_id while priming corpus "${corpus.name}"`);
}
corpus.session_id = sessionId;
this.corpusStore.write(corpus);
return sessionId;
}
async query(corpus: CorpusFile, question: string): Promise<QueryResult> {
if (!corpus.session_id) {
throw new Error(`Corpus "${corpus.name}" has no session — call prime first`);
}
try {
const result = await this.executeQuery(corpus, question);
if (result.session_id !== corpus.session_id) {
corpus.session_id = result.session_id;
this.corpusStore.write(corpus);
}
return result;
} catch (error) {
if (!this.isSessionResumeError(error)) {
if (error instanceof Error) {
logger.error('WORKER', `Query failed for corpus "${corpus.name}"`, {}, error);
} else {
logger.error('WORKER', `Query failed for corpus "${corpus.name}" (non-Error thrown)`, { thrownValue: String(error) });
}
throw error;
}View on GitHub (pinned to d8bc9755e7)