{"record":{"id":"7a4dbfb606dfd749","repo":"thedotmack/claude-mem","slug":"invalid-response","errorCode":"invalid_response","errorMessage":"sessionId is required for endSession","messagePattern":"sessionId is required for endSession","errorType":"validation","errorClass":"ServerClientError","httpStatus":null,"severity":"error","filePath":"src/services/hooks/server-client.ts","lineNumber":226,"sourceCode":"    this.baseUrl = stripTrailingSlash(config.serverBaseUrl);\n    this.apiKey = config.apiKey;\n    this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n  }\n\n  async startSession(input: ServerStartSessionRequest): Promise<ServerStartSessionResponse> {\n    const body = this.buildStartSessionPayload(input);\n    return this.request<ServerStartSessionResponse>('POST', '/v1/sessions/start', body);\n  }\n\n  async recordEvent(input: ServerRecordEventRequest): Promise<ServerRecordEventResponse> {\n    const body = this.buildEventPayload(input);\n    const path = input.generate === false ? '/v1/events?generate=false' : '/v1/events';\n    return this.request<ServerRecordEventResponse>('POST', path, body);\n  }\n\n  async endSession(input: ServerEndSessionRequest): Promise<ServerEndSessionResponse> {\n    if (!input.sessionId) {\n      throw new ServerClientError('invalid_response', 'sessionId is required for endSession');\n    }\n    return this.request<ServerEndSessionResponse>(\n      'POST',\n      `/v1/sessions/${encodeURIComponent(input.sessionId)}/end`,\n      {},\n    );\n  }\n\n  // Phase 8 — direct observation insert (MCP `observation_add`). Calls\n  // `/v1/memories`, which is the canonical write path that MUST NOT enqueue\n  // a generation job. Anti-pattern guard for plan line 770: never duplicate\n  // generation logic in MCP tools.\n  async addObservation(\n    input: ServerAddObservationRequest,\n  ): Promise<ServerAddObservationResponse> {\n    return this.request<ServerAddObservationResponse>(\n      'POST',\n      '/v1/memories',","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d8bc9755e74915e5c3b999181e10a67c889bce2a/src/services/hooks/server-client.ts#L208-L244","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before\nawait client.endSession({ sessionId: session?.id });\n\n// after\nif (session?.id) {\n  await client.endSession({ sessionId: session.id });\n}","handlingStrategy":"validation","validationCode":"if (!input?.sessionId) throw new Error('endSession requires a sessionId from startSession');","typeGuard":"function hasSessionId(input: unknown): input is { sessionId: string } {\n  return typeof input === 'object' && input !== null && typeof (input as any).sessionId === 'string' && (input as any).sessionId.length > 0;\n}","tryCatchPattern":"try {\n  await client.endSession({ sessionId });\n} catch (e) {\n  if (e instanceof ServerClientError && e.code === 'invalid_response') {\n    // no session to end; skip\n  } else throw e;\n}","preventionTips":["Always capture and store the sessionId returned by startSession.","Track session lifecycle state so endSession is only called for started sessions."],"tags":["validation","client","argument"],"backgroundTag":"missing-required-argument","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"}