janhq/jan · error · Error

Failed to fetch repository files

Error message

Failed to fetch repository files

What it means

Thrown after `serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)` returns null or a payload with no `siblings`. `fetchHuggingFaceRepo` itself swallows all errors and returns null on 404/non-OK/parse failure, so this error is the caller's way of detecting a useless repo response. It means the HF API call failed, the repo does not exist, the token is wrong, or the JSON shape was unexpected.

Source

Thrown at web-app/src/containers/MlxModelDownloadAction.tsx:121

          id: downloadedModelId,
          provider: 'mlx',
        },
      },
    })
  }, [navigate, downloadedModelId])

  const handleDownloadMlxModel = useCallback(async () => {
    addLocalDownloadingModel(modelId)

    const modelPath = `${model.developer}/${modelName}`
    try {
      // Fetch repository info to get all files
      const repoInfo = await serviceHub
        .models()
        .fetchHuggingFaceRepo(modelPath, huggingfaceToken)

      if (!repoInfo || !repoInfo.siblings) {
        throw new Error('Failed to fetch repository files')
      }

      // Filter relevant model files for MLX
      const modelFiles = repoInfo.siblings

      if (modelFiles.length === 0) {
        throw new Error('No MLX model files found in repository')
      }

      // Get the MLX engine and import
      const engine = EngineManager.instance().get(
        'mlx'
      )
      if (!engine) {
        throw new Error('MLX engine not found')
      }

      // For MLX, we download the first safetensors file as the main model

View on GitHub (pinned to fad3f12a14)

Solutions

  1. Confirm the HuggingFace token is set, valid, and has `read` scope; prompt the user to re-enter it.
  2. Validate `modelPath` matches `org/repo` and that the repo exists by opening its HF page.
  3. Differentiate the null case (repo not found / network) from the missing-siblings case (malformed API response) so the toast is actionable.
  4. Retry once after a short delay to ride through transient HF 5xx/429 responses.

Example fix

// before
const repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)
if (!repoInfo || !repoInfo.siblings) {
  throw new Error('Failed to fetch repository files')
}

// after
const repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)
if (!repoInfo) {
  throw new Error(
    huggingfaceToken
      ? 'Could not reach HuggingFace. Check the repo name, your token, and connection.'
      : 'Could not reach HuggingFace. A read-scope token may be required for this repo.'
  )
}
if (!repoInfo.siblings) {
  throw new Error('HuggingFace returned an unexpected response (no file list).')
}
Defensive patterns

Strategy: validation

Validate before calling

function isValidModelPath(p: string): boolean {
  return /^[\w.-]+\/[\w.-]+$/.test(p) && !p.startsWith('http')
}
// before calling fetchHuggingFaceRepo:
if (!isValidModelPath(modelPath)) {
  toast.error('Invalid model path', { description: modelPath })
  return
}

Type guard

function hasHfSiblings(repo: unknown): repo is { siblings: { rfilename: string }[] } {
  return (
    typeof repo === 'object' && repo !== null &&
    Array.isArray((repo as any).siblings)
  )
}

Try / catch

try {
  const repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)
  if (!repoInfo) {
    toast.error('Could not reach HuggingFace', {
      description: huggingfaceToken ? 'Check repo name and connection.' : 'A read-scope token may be required.',
    })
    return
  }
  if (!hasHfSiblings(repoInfo)) {
    toast.error('Unexpected HuggingFace response', { description: 'No file list returned.' })
    return
  }
  // proceed
} catch (error) {
  toast.error('Failed to fetch repository files', { description: error instanceof Error ? error.message : String(error) })
}

Prevention

When it happens

Trigger: MLX download flow: `modelPath = `${model.developer}/${modelName}`` resolves to a repo that 404s, a private repo requiring a token the user did not provide, an expired/invalid HuggingFace token (401/403), a network outage, or the HF API returning 200 with a body missing the `siblings` field.

Common situations: User's HuggingFace token expired or lacks `read` scope; the model card has no files (empty repo); rate limiting from HF (429); typo in developer/model name from the hub listing; corporate proxy blocking huggingface.co.

Related errors


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