thedotmack/claude-mem · critical · ServerClientError
missing_api_key
missing_api_key
Error message
Server API key is not configured (CLAUDE_MEM_SERVER_API_KEY).
What it means
The ServerClient's request method refuses to send anything when no API key was configured (empty, whitespace-only, or unset). Every server call (startSession, recordEvent, endSession, addObservation, searchObservations, contextObservations) funnels through request, so all of them fail with code 'missing_api_key'.
Solutions
- Export CLAUDE_MEM_SERVER_API_KEY with a valid server API key before starting the process.
- If using bootstrap, run the server-key bootstrap flow (requires CLAUDE_MEM_SERVER_DATABASE_URL) to generate and store a key.
- Confirm the .env file is loaded before ServerClient is constructed, not after.
- Check the value with trim(): a whitespace-only key is treated as missing.
Example fix
// before
const client = new ServerClient({ baseUrl, apiKey: process.env.CLAUDE_MEM_SERVER_API_KEY }); // undefined
// after
const apiKey = process.env.CLAUDE_MEM_SERVER_API_KEY;
if (!apiKey?.trim()) throw new Error('Set CLAUDE_MEM_SERVER_API_KEY before using ServerClient');
const client = new ServerClient({ baseUrl, apiKey }); Defensive patterns
Strategy: validation
Validate before calling
const apiKey = process.env.CLAUDE_MEM_SERVER_API_KEY;
if (!apiKey || !apiKey.trim()) throw new Error('CLAUDE_MEM_SERVER_API_KEY is not set'); Try / catch
try {
await client.startSession(input);
} catch (e) {
if (e instanceof ServerClientError && e.code === 'missing_api_key') {
logger.warn('Server mode disabled: no API key configured');
return null;
} throw e;
} Prevention
- Bootstrap/generate an API key once and store it in the environment.
- Check key presence at client construction time, not at first request.
- Treat whitespace-only keys as missing (trim before checking).
When it happens
Trigger: Constructing ServerClient without an apiKey (or with '' / whitespace) and then invoking any of its public methods, typically because CLAUDE_MEM_SERVER_API_KEY was not set in the environment when the client was created.
Common situations: Running hooks/server mode locally without the API key exported, .env not loaded at client-construction time, or pointing a client at a server deployment that requires keys while configuring none.
Understand the failure class
Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.
Related errors
- auth_invalid
- auth_invalid
- missing_api_key
- Cannot bootstrap server API key…
- CLAUDE_MEM_HOST_OBSERVER_PORT=
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/889b643fca1ca096.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/hooks/server-client.ts:357
projectId: input.projectId,
sourceType: input.sourceType,
eventType: input.eventType,
occurredAtEpoch: input.occurredAtEpoch,
...(input.serverSessionId !== undefined ? { serverSessionId: input.serverSessionId } : {}),
...(input.contentSessionId !== undefined ? { contentSessionId: input.contentSessionId } : {}),
...(input.memorySessionId !== undefined ? { memorySessionId: input.memorySessionId } : {}),
...(input.platformSource !== undefined ? { platformSource: normalizePlatformSourceField(input.platformSource) } : {}),
...(input.payload !== undefined ? { payload: input.payload } : {}),
};
}
private async request<T>(
method: 'GET' | 'POST',
path: string,
body?: unknown,
): Promise<T> {
if (!this.apiKey || !this.apiKey.trim()) {
throw new ServerClientError(
'missing_api_key',
'Server API key is not configured (CLAUDE_MEM_SERVER_API_KEY).',
);
}
const url = `${this.baseUrl}${path}`;
const init: RequestInit = {
method,
headers: {
'Content-Type': 'application/json',
Authorization: `Bearer ${this.apiKey}`,
},
};
if (body !== undefined) {
init.body = JSON.stringify(body);
}
let response: Response;View on GitHub (pinned to d8bc9755e7)