janhq/jan · error

Provider must have base_url configured

Error message

Provider must have base_url configured

What it means

fetchTopRemoteModels throws this when the provider passes the catalog-kind check but has no base_url, which is mandatory to issue the models-list HTTP request. It is an early configuration validation so the caller gets a clear message instead of a malformed-URL fetch failure.

Solutions

  1. Set the provider's base_url in Settings > Model Providers (e.g. https://api.openai.com/v1).
  2. Validate base_url is a non-empty, well-formed URL before calling fetchTopRemoteModels.
  3. For catalog UI, hide/disable 'fetch models' until base_url is populated.

Example fix

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

Strategy: validation

Validate before calling

let u
try { u = new URL(provider.base_url || '') } catch { u = null }
if (!u || !/^https?:$/.test(u.protocol)) { promptForBaseUrl(provider); return }

Type guard

const hasBaseUrl = (p) => typeof p.base_url === 'string' && p.base_url.trim().length > 0

Try / catch

try { await fetchTopRemoteModels(provider, fetch) } catch (e) { if (e.message.includes('base_url configured')) { openBaseUrlSettings(provider) } else throw e }

Prevention

When it happens

Trigger: Remote provider record saved without a base URL; base_url deleted or whitespace-only during editing; provider created programmatically with only provider name and api_key.

Common situations: Fresh provider entry where the user added a key but not the endpoint; migration/import dropping base_url; templated providers expecting the user to fill in the URL.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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

Appendix: source

Thrown at web-app/src/lib/remoteModelCatalog.ts:205

  }
  return {
    ok: response.ok,
    status: response.status,
    statusText: response.statusText,
    body,
  }
}

export async function fetchTopRemoteModels(
  provider: ProviderLike,
  fetchImpl: FetchImpl
): Promise<RemoteCatalogModel[]> {
  const kind = resolveCatalogKind(provider)
  if (!kind) {
    throw new Error(`Catalog not supported for ${provider.provider}`)
  }
  if (!provider.base_url) {
    throw new Error('Provider must have base_url configured')
  }

  const keyChain = providerRemoteApiKeyChain(provider)
  const attempts: (string | undefined)[] = keyChain.length > 0 ? keyChain : [undefined]

  let lastStatus = 0
  let lastStatusText = ''
  for (let i = 0; i < attempts.length; i++) {
    const result = await getJson(
      fetchImpl,
      `${provider.base_url}/models`,
      buildHeaders(provider, attempts[i])
    )
    lastStatus = result.status
    lastStatusText = result.statusText
    if (!result.ok) {
      if ([401, 403, 429].includes(result.status) && i < attempts.length - 1) continue
      throw new Error(`Failed to fetch models from ${provider.provider}: ${result.status} ${result.statusText}`)

View on GitHub (pinned to 7205d770c1)