janhq/jan · error

Models endpoint not found for

Error message

Models endpoint not found for ${provider.provider}. Check the base URL configuration.

What it means

Thrown when the provider's /models endpoint responds with HTTP 404. The service is reachable and authenticated but there is no /models route at the configured base URL, almost always because the base URL is wrong, missing a version path (e.g. /v1), or points at a server exposing a different API surface.

Solutions

  1. Fix the base URL to include the full API root, e.g. 'https://api.openai.com/v1'.
  2. Confirm the endpoint's model-list route with curl: `curl <base_url>/models`.
  3. If the server uses a non-standard route, add a custom_header/proxy or point base_url at a compatible path.
  4. Check reverse-proxy/nginx routing so /models reaches the backend.

Example fix

// before
base_url: 'https://api.openai.com'
// after
base_url: 'https://api.openai.com/v1'
Defensive patterns

Strategy: validation

Validate before calling

function looksLikeApiRoot(url: string): boolean {
  try { const u = new URL(url); return u.pathname === '' || /v\d+|api|v1/.test(u.pathname) } catch { return false }
}
if (!looksLikeApiRoot(provider.base_url)) throw new Error('base_url should be the full API root, e.g. https://api.openai.com/v1')

Type guard

function isValidHttpUrl(v: string): boolean {
  try { const u = new URL(v); return u.protocol === 'http:' || u.protocol === 'https:' } catch { return false }
}

Try / catch

try {
  await fetchModelsFromProvider(provider)
} catch (e) {
  if (e instanceof Error && e.message.startsWith('Models endpoint not found')) {
    promptFixBaseUrl(provider.provider) // suggest appending /v1
  }
}

Prevention

When it happens

Trigger: GET `${provider.base_url}/models` returned 404; e.g. base_url 'https://api.openai.com' (missing /v1) or an llamacpp/Ollama server without that route mounted.

Common situations: Base URL typed without the /v1 (or /api) prefix; pointing at the chat/completions host instead of the API root; self-hosted llama.cpp server with a different route layout; reverse proxy stripping or not routing the path.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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

Appendix: source

Thrown at web-app/src/services/providers/tauri.ts:213

          [401, 403, 429].includes(response.status) &&
          ki < keyAttempts.length - 1
        ) {
          continue
        }

        if (!response.ok) {
          if (response.status === 401) {
            throw new Error(
              `Authentication failed: API key is required or invalid for ${provider.provider}`
            )
          }
          if (response.status === 403) {
            throw new Error(
              `Access forbidden: Check your API key permissions for ${provider.provider}`
            )
          }
          if (response.status === 404) {
            throw new Error(
              `Models endpoint not found for ${provider.provider}. Check the base URL configuration.`
            )
          }
          throw new Error(
            `Failed to fetch models from ${provider.provider}: ${response.status} ${response.statusText}`
          )
        }

        const data = await response.json()

        if (data.data && Array.isArray(data.data)) {
          return data.data
            .map((model: { id: string }) => model.id)
            .filter(Boolean)
        }
        if (Array.isArray(data)) {
          return data
            .filter(Boolean)

View on GitHub (pinned to 7205d770c1)