{"record":{"id":"b536f607a9a3ed7a","repo":"janhq/jan","slug":"failed-to-fetch-repository-files","errorCode":null,"errorMessage":"Failed to fetch repository files","messagePattern":"Failed to fetch repository files","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"web-app/src/containers/MlxModelDownloadAction.tsx","lineNumber":121,"sourceCode":"          id: downloadedModelId,\n          provider: 'mlx',\n        },\n      },\n    })\n  }, [navigate, downloadedModelId])\n\n  const handleDownloadMlxModel = useCallback(async () => {\n    addLocalDownloadingModel(modelId)\n\n    const modelPath = `${model.developer}/${modelName}`\n    try {\n      // Fetch repository info to get all files\n      const repoInfo = await serviceHub\n        .models()\n        .fetchHuggingFaceRepo(modelPath, huggingfaceToken)\n\n      if (!repoInfo || !repoInfo.siblings) {\n        throw new Error('Failed to fetch repository files')\n      }\n\n      // Filter relevant model files for MLX\n      const modelFiles = repoInfo.siblings\n\n      if (modelFiles.length === 0) {\n        throw new Error('No MLX model files found in repository')\n      }\n\n      // Get the MLX engine and import\n      const engine = EngineManager.instance().get(\n        'mlx'\n      )\n      if (!engine) {\n        throw new Error('MLX engine not found')\n      }\n\n      // For MLX, we download the first safetensors file as the main model","sourceCodeStart":103,"sourceCodeEnd":139,"githubUrl":"https://github.com/janhq/jan/blob/fad3f12a147d138388a66f0d92a02b2675f65294/web-app/src/containers/MlxModelDownloadAction.tsx#L103-L139","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Confirm the HuggingFace token is set, valid, and has `read` scope; prompt the user to re-enter it.","Validate `modelPath` matches `org/repo` and that the repo exists by opening its HF page.","Differentiate the null case (repo not found / network) from the missing-siblings case (malformed API response) so the toast is actionable.","Retry once after a short delay to ride through transient HF 5xx/429 responses."],"exampleFix":"// before\nconst repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)\nif (!repoInfo || !repoInfo.siblings) {\n  throw new Error('Failed to fetch repository files')\n}\n\n// after\nconst repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)\nif (!repoInfo) {\n  throw new Error(\n    huggingfaceToken\n      ? 'Could not reach HuggingFace. Check the repo name, your token, and connection.'\n      : 'Could not reach HuggingFace. A read-scope token may be required for this repo.'\n  )\n}\nif (!repoInfo.siblings) {\n  throw new Error('HuggingFace returned an unexpected response (no file list).')\n}","handlingStrategy":"validation","validationCode":"function isValidModelPath(p: string): boolean {\n  return /^[\\w.-]+\\/[\\w.-]+$/.test(p) && !p.startsWith('http')\n}\n// before calling fetchHuggingFaceRepo:\nif (!isValidModelPath(modelPath)) {\n  toast.error('Invalid model path', { description: modelPath })\n  return\n}","typeGuard":"function hasHfSiblings(repo: unknown): repo is { siblings: { rfilename: string }[] } {\n  return (\n    typeof repo === 'object' && repo !== null &&\n    Array.isArray((repo as any).siblings)\n  )\n}","tryCatchPattern":"try {\n  const repoInfo = await serviceHub.models().fetchHuggingFaceRepo(modelPath, huggingfaceToken)\n  if (!repoInfo) {\n    toast.error('Could not reach HuggingFace', {\n      description: huggingfaceToken ? 'Check repo name and connection.' : 'A read-scope token may be required.',\n    })\n    return\n  }\n  if (!hasHfSiblings(repoInfo)) {\n    toast.error('Unexpected HuggingFace response', { description: 'No file list returned.' })\n    return\n  }\n  // proceed\n} catch (error) {\n  toast.error('Failed to fetch repository files', { description: error instanceof Error ? error.message : String(error) })\n}","preventionTips":["Validate the model path shape (org/repo) before the API call.","Keep the HuggingFace token fresh with read scope.","Differentiate null (not found/network) from missing-siblings (malformed) in the user message."],"tags":["huggingface","mlx","network","download"],"backgroundTag":null,"analyzedSha":"fad3f12a147d138388a66f0d92a02b2675f65294","analyzedAt":"2026-08-12T20:33:47.516Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}