nextai-translator/nextai-translator · error · Error
Invalid API key
Error message
Invalid API key
What it means
LiteLLM's listModels() maps HTTP 401 or 403 from the GET /models request to 'Invalid API key'. The virtual-key/Bearer token passed in the Authorization header was rejected by the LiteLLM proxy. Called via the public models() wrapper.
Source
Thrown at src/common/engines/litellm.ts:37
return []
}
const url = urlJoin(apiURL, '/v1/models')
const fetcher = getUniversalFetch()
const headers: Record<string, string> = {
'Content-Type': 'application/json',
}
// A LiteLLM proxy usually requires a virtual/master key, but some run
// without auth, so only send the header when a key is configured.
if (apiKey) {
headers['Authorization'] = `Bearer ${apiKey}`
}
const response = await fetcher(url, {
method: 'GET',
headers,
})
if (response.status !== 200) {
if (response.status === 401 || response.status === 403) {
throw new Error('Invalid API key')
}
if (response.status === 404) {
throw new Error('Invalid API URL')
}
throw new Error(`Failed to list models: ${response.statusText}`)
}
const json = await response.json()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return json.data.map((model: any) => {
return {
id: model.id,
name: model.id,
}
})
}
async getAPIModel(): Promise<string> {
const settings = await getSettings()View on GitHub (pinned to f57537ee4a)
Solutions
- Verify/generate a valid virtual key in the LiteLLM proxy admin UI and re-enter it in settings
- Test the key directly: curl -H 'Authorization: Bearer <key>' <proxy>/v1/models
- Confirm the key has access to the models route and the allowed-models list is not empty
- Check the configured LiteLLM proxy base URL matches your deployment
Example fix
// before
const models = await litellm.models('') // empty key → 401
// after
const key = settings.litellmApiKey?.trim()
if (!key) throw new Error('Set your LiteLLM virtual key in settings')
const models = await litellm.models(key) Defensive patterns
Strategy: validation
Validate before calling
const key = apiKey?.trim()
if (!key) throw new Error('LiteLLM virtual key missing')
const probe = await fetch(`${proxyBase}/v1/models`, { headers: { Authorization: `Bearer ${key}` } })
if (probe.status === 401 || probe.status === 403) throw new Error('LiteLLM key rejected by proxy') Type guard
function isNonEmptyKey(k: unknown): k is string {
return typeof k === 'string' && k.trim().length > 0
} Try / catch
try {
const models = await litellm.models(apiKey)
} catch (e) {
if (e instanceof Error && e.message === 'Invalid API key') {
openSettings('LiteLLM proxy rejected the key — regenerate a virtual key in the proxy UI')
} else { throw e }
} Prevention
- Regenerate and re-enter the virtual key whenever proxy admins rotate keys
- Trim keys on input
- Grant the key access to the models route in the proxy config
- Smoke-test the key with curl against /v1/models before saving
When it happens
Trigger: Calling listModels() (or models()) on the LiteLLM engine when the proxy responds 401/403: the LiteLLM virtual key is wrong, expired, deleted, lacks model access, or no Authorization header was sent at all.
Common situations: Admin rotated/deleted a virtual key in the LiteLLM proxy UI; key typed with trailing whitespace; key created without permissions for the /models route; pointing at a proxy that requires auth while settings have an empty key field.
Understand the failure class
- Authentication and authorization failures — expired tokens, bad credentials, and missing scopes.
Related errors
- Invalid API key
- Invalid API Key
- Invalid API key
- ChatGPT is not login
- Failed to fetch models: ${resp.statusText}
AI-assisted analysis of nextai-translator/nextai-translator@f57537ee4a (2026-08-31).
Data as JSON: /api/errors/bb637f652c2725cb.
Report an issue: GitHub.