{"record":{"id":"4a19c3eaf890966a","repo":"nextai-translator/nextai-translator","slug":"invalid-api-key","errorCode":null,"errorMessage":"Invalid API key","messagePattern":"Invalid API key","errorType":"http","errorClass":"Error","httpStatus":401,"severity":"error","filePath":"src/common/engines/deepseek.ts","lineNumber":26,"sourceCode":"        let apiKey = apiKey_\n        if (!apiKey) {\n            apiKey = await this.getAPIKey()\n        }\n        const apiURL = await this.getAPIURL()\n        if (!apiKey || !apiURL) {\n            return []\n        }\n        const url = urlJoin(apiURL, '/v1/models')\n        const response = await fetch(url, {\n            method: 'GET',\n            headers: {\n                'Content-Type': 'application/json',\n                'Authorization': `Bearer ${apiKey}`,\n            },\n        })\n        if (response.status !== 200) {\n            if (response.status === 401) {\n                throw new Error('Invalid API key')\n            }\n            if (response.status === 404) {\n                throw new Error('Invalid API URL')\n            }\n            if (response.status === 403) {\n                throw new Error('Invalid API Key')\n            }\n            throw new Error(`Failed to list models: ${response.statusText}`)\n        }\n        const json = await response.json()\n        // eslint-disable-next-line @typescript-eslint/no-explicit-any\n        return json.data.map((model: any) => {\n            return {\n                id: model.id,\n                name: model.id,\n            }\n        })\n    }","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/nextai-translator/nextai-translator/blob/f57537ee4ad8ec654cb726b9907bab7a1f82601d/src/common/engines/deepseek.ts#L8-L44","documentation":"DeepSeek's listModels() checks the GET /models response status and maps 401 to 'Invalid API key'. This means the DeepSeek server rejected the Bearer token supplied in the Authorization header. It is a deliberate, specific mapping so users know the credential — not the network — is the problem.","triggerScenarios":"Calling DeepSeek.listModels(apiKey) when the API returns HTTP 401: the apiKey is undefined/wrong/revoked, contains whitespace or a truncated copy-paste, or the key was created for a different service (e.g. OpenAI key pasted into DeepSeek settings).","commonSituations":"Copy-pasting the key with surrounding spaces; regenerating the key on platform.deepseek.com and not updating the app settings; using an old free-credit key after it expired; mixing up providers when configuring multiple engines.","solutions":["Go to platform.deepseek.com → API Keys, create a fresh key, and paste it into the DeepSeek settings without extra spaces","Confirm you are using a DeepSeek key, not a key from another provider","Check the API base URL in settings points to https://api.deepseek.com (a wrong URL can produce different status codes)","Retry the model list after saving the new key"],"exampleFix":"// before\nconst key = process.env.DEEPSEEK_KEY!.trim().slice(0, 40) // truncated!\nawait deepseek.listModels(key)\n// after\nconst key = process.env.DEEPSEEK_KEY?.trim()\nif (!key) throw new Error('DEEPSEEK_KEY is not set')\nawait deepseek.listModels(key)","handlingStrategy":"validation","validationCode":"const key = apiKey?.trim()\nif (!key || !key.startsWith('sk-')) {\n  throw new Error('DeepSeek API key missing or malformed (expected sk-...)')\n}","typeGuard":"function isDeepSeekKey(k: unknown): k is string {\n  return typeof k === 'string' && /^sk-\\S{20,}$/.test(k.trim())\n}","tryCatchPattern":"try {\n  const models = await deepseek.listModels(apiKey)\n} catch (e) {\n  if (e instanceof Error && e.message === 'Invalid API key') {\n    openSettings('DeepSeek API key rejected — generate a new one at platform.deepseek.com')\n  } else { throw e }\n}","preventionTips":["Paste keys freshly and trimmed; never hand-truncate","Rotate keys on the platform and update settings immediately","Keep separate env vars per provider to avoid cross-pasting keys","Probe /models with curl once after configuring a new key"],"tags":["authentication","api-key","http-401","deepseek"],"backgroundTag":"invalid-api-key","analyzedSha":"f57537ee4ad8ec654cb726b9907bab7a1f82601d","analyzedAt":"2026-08-31T11:24:08.384Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}