janhq/jan · error

Failed to fetch model catalog

Error message

Failed to fetch model catalog: ${error instanceof Error ? error.message : 'Unknown error'}

What it means

The catch block of fetchModelCatalog rethrows any failure (network error, JSON parse failure, or the non-OK throw above) as a wrapped 'Failed to fetch model catalog' error. It preserves the original message when the cause is an Error.

Solutions

  1. Check internet connectivity and retry
  2. Inspect the wrapped inner message for the root cause (network vs JSON)
  3. Validate the catalog endpoint returns valid JSON
  4. Add a timeout and offline fallback catalog

Example fix

// before
throw new Error(`Failed to fetch model catalog: ${error instanceof Error ? error.message : 'Unknown error'}`)
// after
if (error instanceof TypeError) throw new Error('Network unavailable: could not fetch model catalog')
throw new Error(`Failed to fetch model catalog: ${error instanceof Error ? error.message : 'Unknown error'}`)
Defensive patterns

Strategy: retry

Validate before calling

if (!navigator.onLine) throw new Error('Offline: model catalog unavailable')

Type guard

null

Try / catch

try { catalog = await fetchModelCatalog() } catch (e) { log.warn(e); catalog = await loadCachedCatalog() }

Prevention

When it happens

Trigger: fetch() rejects (DNS failure, offline, CORS), response.json() fails on invalid JSON, or the inner non-OK throw is caught and rewrapped.

Common situations: No internet connection, catalog server returning malformed JSON, CORS blocking the request in the webview, or certificate errors.

Related errors


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

Appendix: source

Thrown at web-app/src/services/models/default.ts:74

  async fetchModels(): Promise<modelInfo[]> {
    return this.getEngine()?.list() ?? []
  }

  async fetchModelCatalog(): Promise<ModelCatalog> {
    try {
      const response = await fetch(MODEL_CATALOG_URL)

      if (!response.ok) {
        throw new Error(
          `Failed to fetch model catalog: ${response.status} ${response.statusText}`
        )
      }

      const catalog: ModelCatalog = await response.json()
      return catalog
    } catch (error) {
      console.error('Error fetching model catalog:', error)
      throw new Error(
        `Failed to fetch model catalog: ${error instanceof Error ? error.message : 'Unknown error'}`
      )
    }
  }

  async fetchLatestJanModel(): Promise<CatalogModel | null> {
    try {
      const response = await fetch(LATEST_JAN_MODEL_URL)

      if (!response.ok) {
        console.error(
          `Failed to fetch latest Jan model: ${response.status} ${response.statusText}`
        )
        return null
      }

      const data = await response.json()

View on GitHub (pinned to 7205d770c1)