thedotmack/claude-mem · error · ServerClientError
invalid_response
invalid_response
Error message
sessionId is required for endSession
What it means
endSession validates its input before making any HTTP call: a ServerEndSessionRequest must carry a truthy sessionId. If it is missing, empty, or undefined, the client throws ServerClientError with code 'invalid_response' immediately instead of issuing a malformed request to the server.
Solutions
- Ensure startSession succeeded and pass its returned sessionId to endSession.
- Check input.sessionId before calling; skip endSession if no session was ever created.
- Persist the sessionId (state, closure, DB) so it is available at session end.
Example fix
// before
await client.endSession({ sessionId: session?.id });
// after
if (session?.id) {
await client.endSession({ sessionId: session.id });
} Defensive patterns
Strategy: validation
Validate before calling
if (!input?.sessionId) throw new Error('endSession requires a sessionId from startSession'); Type guard
function hasSessionId(input: unknown): input is { sessionId: string } {
return typeof input === 'object' && input !== null && typeof (input as any).sessionId === 'string' && (input as any).sessionId.length > 0;
} Try / catch
try {
await client.endSession({ sessionId });
} catch (e) {
if (e instanceof ServerClientError && e.code === 'invalid_response') {
// no session to end; skip
} else throw e;
} Prevention
- Always capture and store the sessionId returned by startSession.
- Track session lifecycle state so endSession is only called for started sessions.
When it happens
Trigger: Calling client.endSession({}) or endSession({ sessionId: '' }) — e.g. when a session was never started, startSession failed earlier and its returned sessionId was never captured, or the id was lost between async steps.
Common situations: Ending a session after a failed startSession, passing an untyped/loosely-typed object literal, or reading sessionId from an optional server response field that was undefined.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Adapter rejected input
- agent_event source_id must belong to project_id and team_id
- canonical content
- canonical content
- CLAUDE_MEM_REDIS_URL must use redis:// or rediss://
AI-assisted analysis of thedotmack/claude-mem@d8bc9755e7 (2026-09-17).
Data as JSON: /api/errors/7a4dbfb606dfd749.
Report an issue: GitHub.
Appendix: source
Thrown at src/services/hooks/server-client.ts:226
this.baseUrl = stripTrailingSlash(config.serverBaseUrl);
this.apiKey = config.apiKey;
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;
}
async startSession(input: ServerStartSessionRequest): Promise<ServerStartSessionResponse> {
const body = this.buildStartSessionPayload(input);
return this.request<ServerStartSessionResponse>('POST', '/v1/sessions/start', body);
}
async recordEvent(input: ServerRecordEventRequest): Promise<ServerRecordEventResponse> {
const body = this.buildEventPayload(input);
const path = input.generate === false ? '/v1/events?generate=false' : '/v1/events';
return this.request<ServerRecordEventResponse>('POST', path, body);
}
async endSession(input: ServerEndSessionRequest): Promise<ServerEndSessionResponse> {
if (!input.sessionId) {
throw new ServerClientError('invalid_response', 'sessionId is required for endSession');
}
return this.request<ServerEndSessionResponse>(
'POST',
`/v1/sessions/${encodeURIComponent(input.sessionId)}/end`,
{},
);
}
// Phase 8 — direct observation insert (MCP `observation_add`). Calls
// `/v1/memories`, which is the canonical write path that MUST NOT enqueue
// a generation job. Anti-pattern guard for plan line 770: never duplicate
// generation logic in MCP tools.
async addObservation(
input: ServerAddObservationRequest,
): Promise<ServerAddObservationResponse> {
return this.request<ServerAddObservationResponse>(
'POST',
'/v1/memories',View on GitHub (pinned to d8bc9755e7)