janhq/jan · error

No API key configured for

Error message

No API key configured for ${provider.provider}. Add one in Settings > Model Providers.

What it means

requireRemoteApiKey throws this when neither the provided key chain nor the provider's stored api_key yields a non-empty key. An empty apiKey still sends an empty auth header upstream, which produces misleading 401s (e.g. Anthropic's 'x-api-key header is required'), so the library fails early with an actionable message pointing at settings.

Solutions

  1. Add an API key in Settings > Model Providers for this provider.
  2. Populate the key chain (e.g. from env/config) before invoking the fetch.
  3. Validate provider.api_key is non-empty at load time and surface a settings prompt instead of failing mid-request.

Example fix

// before
const provider = { provider: 'anthropic', base_url: 'https://api.anthropic.com' }
// after
const provider = { provider: 'anthropic', base_url: 'https://api.anthropic.com', api_key: process.env.ANTHROPIC_API_KEY }
Defensive patterns

Strategy: validation

Validate before calling

if (!provider.api_key?.trim() && !(keyChain?.length)) {
  openSettingsPrompt(`Add an API key for ${provider.provider}`)
  return
}

Type guard

const hasApiKey = (p) => typeof p.api_key === 'string' && p.api_key.trim().length > 0

Try / catch

try { await fetchTopRemoteModels(provider, fetch) } catch (e) { if (e.message.startsWith('No API key configured')) { router.push('/settings/providers'); } else throw e }

Prevention

When it happens

Trigger: Calling a remote provider (fetchTopRemoteModels or chat) with a provider record whose api_key is null/empty and no key in the key chain; user cleared the key field; provider created from a template without credentials.

Common situations: Fresh install with no keys configured; switching a provider to a remote endpoint that requires auth; environment variable supplying an empty string; accidentally trimming away a whitespace-only key.

Understand the failure class

Background: "API key is required" / "API key not found" / "No API key was set": the missing-api-key error family across 16 libraries — this error's family across 16 libraries.

Related errors


AI-assisted analysis of janhq/jan@7205d770c1 (2026-09-17). Data as JSON: /api/errors/41fca4fdfeafaede. Report an issue: GitHub.

Appendix: source

Thrown at web-app/src/lib/model-factory.ts:883

        res.body?.cancel().catch(() => {})
        continue
      }
      return res
    }
    throw new Error('API key rotation exhausted')
  }
}

// An empty apiKey still puts an empty auth header on the wire, which upstreams
// answer with misleading 401s (e.g. Anthropic's "x-api-key header is
// required"). Fail here with an actionable message instead.
function requireRemoteApiKey(
  provider: ProviderObject,
  keyChain: string[]
): string {
  const key = keyChain[0] ?? provider.api_key?.trim()
  if (!key) {
    throw new Error(
      `No API key configured for ${provider.provider}. Add one in Settings > Model Providers.`
    )
  }
  return key
}

function getRuntimeFetch(): typeof globalThis.fetch {
  const maybeWindow = globalThis as typeof globalThis & {
    __TAURI__?: unknown
    __TAURI_INTERNALS__?: unknown
  }
  const hasTauriRuntime =
    typeof maybeWindow.__TAURI__ !== 'undefined' ||
    typeof maybeWindow.__TAURI_INTERNALS__ !== 'undefined'

  return isPlatformTauri() && hasTauriRuntime
    ? (httpFetch as typeof globalThis.fetch)
    : globalThis.fetch

View on GitHub (pinned to 7205d770c1)