janhq/jan · warning · Error

Failed to fetch HuggingFace repository: ${response.status} $

Error message

Failed to fetch HuggingFace repository: ${response.status} ${response.statusText}

What it means

Thrown by ModelService.fetchHuggingFaceRepo (default.ts:121) when the HuggingFace API response is non-OK and not 404. (404 is handled above by returning null.) Embeds response.status and statusText. The surrounding catch swallows the error and returns null, so callers see null rather than the throw — the throw mainly distinguishes 404 (legit 'not found') from other failures in logs.

Source

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

        return null
      }

      const response = await fetch(
        `https://huggingface.co/api/models/${cleanRepoId}?blobs=true&files_metadata=true`,
        {
          headers: hfToken
            ? {
                Authorization: `Bearer ${hfToken}`,
              }
            : {},
        }
      )

      if (!response.ok) {
        if (response.status === 404) {
          return null // Repository not found
        }
        throw new Error(
          `Failed to fetch HuggingFace repository: ${response.status} ${response.statusText}`
        )
      }

      const repoData = await response.json()
      return repoData
    } catch (error) {
      console.error('Error fetching HuggingFace repository:', error)
      return null
    }
  }

  convertHfRepoToCatalogModel(repo: HuggingFaceRepo): CatalogModel {
    // Format file size helper
    const formatFileSize = (size?: number) => {
      if (!size) return 'Unknown size'
      if (size < 1024 ** 3) return `${(size / 1024 ** 2).toFixed(1)} MB`
      return `${(size / 1024 ** 3).toFixed(1)} GB`

View on GitHub (pinned to fad3f12a14)

Solutions

  1. For private repos, set a valid HuggingFace access token in settings so the Authorization: Bearer header is sent.
  2. For 429, slow down repo lookups or authenticate to raise the rate limit.
  3. For 5xx, retry — HuggingFace incidents are usually short.
  4. Treat null return as 'not found or unavailable' and prompt the user to verify the repo id.

Example fix

// before
if (!response.ok) {
  if (response.status === 404) return null
  throw new Error(`Failed to fetch HuggingFace repository: ${response.status} ${response.statusText}`)
}
// after: surface auth/rate-limit distinctly before swallowing to null
if (!response.ok) {
  if (response.status === 404) return null
  if (response.status === 401 || response.status === 403) {
    console.warn('HuggingFace auth failed — set a token in Settings for private repos')
  }
  throw new Error(`Failed to fetch HuggingFace repository: ${response.status} ${response.statusText}`)
}
Defensive patterns

Strategy: fallback

Validate before calling

function looksLikePrivateRepo(repoId: string, hasToken: boolean): boolean {
  return Boolean(repoId) && !hasToken && repoId.split('/')[0] !== defaultPublicNamespace
}
// before fetchHuggingFaceRepo, prompt for a token when a private repo is suspected.

Type guard

function isHfRepo(x: unknown): x is HuggingFaceRepo {
  return typeof x === 'object' && x !== null && 'siblings' in x
}

Try / catch

try {
  return await this.fetchHuggingFaceRepo(repoId, hfToken)
} catch (e) {
  console.error('HF repo lookup failed', e)
  return null  // match the function's existing null-on-failure contract
}

Prevention

When it happens

Trigger: GET https://huggingface.co/api/models/{repoId}?blobs=true&files_metadata=true returns 401/403 (private repo, token invalid/missing), 429 (rate-limited), or 5xx (HuggingFace incident). 404 is intentionally converted to null before this throw.

Common situations: User pasted a private repo id without setting a HuggingFace token (401/403); HuggingFace rate-limits unauthenticated requests (429); the hfToken passed is expired; transient HuggingFace outage (5xx).

Related errors


AI-assisted analysis of janhq/jan@fad3f12a14 (2026-08-12). Data as JSON: /api/errors/9b4399545ba4df1b. Report an issue: GitHub.