{"record":{"id":"73bf8cc383e68b92","repo":"thedotmack/claude-mem","slug":"invalid-api-key-check-your-api-key-configuration","errorCode":null,"errorMessage":"Invalid API key: check your API key configuration in ~/.claude-mem/settings.json or ~/.claude-mem/.env","messagePattern":"Invalid API key: check your API key configuration in ~/\\.claude-mem/settings\\.json or ~/\\.claude-mem/\\.env","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/services/worker/ClaudeProvider.ts","lineNumber":382,"sourceCode":"            });\n          }\n\n          const discoveryTokens = (session.cumulativeInputTokens + session.cumulativeOutputTokens) - tokensBeforeResponse;\n\n          const originalTimestamp = session.earliestPendingTimestamp;\n\n          if (responseSize > 0) {\n            const truncatedResponse = responseSize > 100\n              ? textContent.substring(0, 100) + '...'\n              : textContent;\n            logger.dataOut('SDK', `Response received (${responseSize} chars)`, {\n              sessionId: session.sessionDbId,\n              promptNumber: session.lastPromptNumber\n            }, truncatedResponse);\n          }\n\n          if (typeof textContent === 'string' && textContent.includes('Invalid API key')) {\n            throw new Error('Invalid API key: check your API key configuration in ~/.claude-mem/settings.json or ~/.claude-mem/.env');\n          }\n\n          await processAgentResponse(\n            textContent,\n            session,\n            this.dbManager,\n            this.sessionManager,\n            worker,\n            discoveryTokens,\n            originalTimestamp,\n            'SDK',\n            cwdTracker.lastCwd,\n            modelId,\n            activeResponseContext.current\n          );\n        }\n\n        if (message.type === 'result') {","sourceCodeStart":364,"sourceCodeEnd":400,"githubUrl":"https://github.com/thedotmack/claude-mem/blob/d768ba364302d12b76e69e4f021f0bb1d2d50ed6/src/services/worker/ClaudeProvider.ts#L364-L400","documentation":"Thrown by ClaudeProvider when the SDK's response text literally contains the substring 'Invalid API key'. The provider treats this in-band text as a hard auth failure because the SDK sometimes returns a 200 with an error body rather than a proper non-2xx. It points the user at the two key configuration locations.","triggerScenarios":"Inside the SDK message loop, after receiving assistant textContent: if typeof textContent === 'string' && textContent.includes('Invalid API key'), throw. The substring match is intentionally broad, so any response containing that phrase triggers it.","commonSituations":"ANTHROPIC_API_KEY (or the configured key) is missing, expired, revoked, copied with extra whitespace, or for the wrong workspace; the key has insufficient permissions/credits; or a proxy/gateway returns an 'Invalid API key' body. Common after rotating keys, in CI without the secret, or when a key from another provider is set.","solutions":["Check ~/.claude-mem/settings.json and ~/.claude-mem/.env for the API key and update it to a valid, active key.","Confirm the key is not expired/revoked and has credit/permission for the configured model.","Remove leading/trailing whitespace or quotes around the key value.","Verify the env var name the provider reads (e.g. ANTHROPIC_API_KEY) is exported in the worker process.","If behind a proxy, ensure the proxy forwards the Authorization header and isn't injecting its own error body."],"exampleFix":"# before: ANTHROPIC_API_KEY=sk-ant-...EXPIRED...\n# after:  ANTHROPIC_API_KEY=sk-ant-...VALID...  (in ~/.claude-mem/.env or settings.json)","handlingStrategy":"validation","validationCode":"import { readFileSync, existsSync } from 'fs';\nfunction resolveApiKey(env: NodeJS.ProcessEnv = process.env): string {\n  const fromEnv = (env.ANTHROPIC_API_KEY ?? '').trim();\n  if (fromEnv) return fromEnv;\n  const envPath = process.env.HOME + '/.claude-mem/.env';\n  if (existsSync(envPath)) {\n    const kv = Object.fromEntries(readFileSync(envPath, 'utf-8').split('\\n').filter(Boolean).map(l => l.split('=')));\n    if (kv.ANTHROPIC_API_KEY) return kv.ANTHROPIC_API_KEY.trim();\n  }\n  throw new Error('ANTHROPIC_API_KEY missing; configure ~/.claude-mem/.env before starting the worker');\n}","typeGuard":null,"tryCatchPattern":"try { resolveApiKey(); /* before worker start */ }\ncatch (e) { logger.error('CONFIG', (e as Error).message); process.exit(1); }\n// and around the SDK loop:\ntry { /* run sdk loop */ }\ncatch (e) {\n  if (e instanceof Error && e.message.startsWith('Invalid API key')) {\n    logger.error('AUTH', e.message); stopWorkerForOperatorIntervention(); return;\n  }\n  throw e;\n}","preventionTips":["Resolve and validate the API key at worker startup, not mid-loop.","Store keys in ~/.claude-mem/.env or settings.json and restrict file perms.","After key rotation, restart the worker so it picks up the new value.","Use a substring narrower than 'Invalid API key' for masking if logging response bodies."],"tags":["worker","claude-provider","auth","api-key","configuration"],"backgroundTag":null,"analyzedSha":"d768ba364302d12b76e69e4f021f0bb1d2d50ed6","analyzedAt":"2026-08-12T23:52:55.241Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}