{"record":{"id":"6df03c0a4d6ef6ad","repo":"jamiepine/voicebox","slug":"failed-to-fetch-model-info-response-status","errorCode":null,"errorMessage":"Failed to fetch model info: ${response.status}","messagePattern":"Failed to fetch model info: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"app/src/components/ServerSettings/ModelManagement.tsx","lineNumber":51,"sourceCode":"import { Button } from '@/components/ui/button';\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogHeader,\n  DialogTitle,\n} from '@/components/ui/dialog';\nimport { Progress } from '@/components/ui/progress';\nimport { useToast } from '@/components/ui/use-toast';\nimport { apiClient } from '@/lib/api/client';\nimport type { ActiveDownloadTask, HuggingFaceModelInfo, ModelStatus } from '@/lib/api/types';\nimport { useModelDownloadToast } from '@/lib/hooks/useModelDownloadToast';\nimport { usePlatform } from '@/platform/PlatformContext';\nimport { useServerStore } from '@/stores/serverStore';\n\nasync function fetchHuggingFaceModelInfo(repoId: string): Promise<HuggingFaceModelInfo> {\n  const response = await fetch(`https://huggingface.co/api/models/${repoId}`);\n  if (!response.ok) throw new Error(`Failed to fetch model info: ${response.status}`);\n  return response.json();\n}\n\nconst MODEL_DESCRIPTIONS: Record<string, string> = {\n  'qwen-tts-1.7B':\n    'High-quality multilingual TTS by Alibaba. Supports 10 languages with natural prosody and voice cloning from short reference audio.',\n  'qwen-tts-0.6B':\n    'Lightweight version of Qwen TTS. Same language support with faster inference, ideal for lower-end hardware.',\n  luxtts:\n    'Lightweight ZipVoice-based TTS designed for high quality voice cloning and 48kHz speech generation at speeds exceeding 150x realtime.',\n  'chatterbox-tts':\n    'Production-grade open source TTS by Resemble AI. Supports 23 languages with voice cloning and emotion exaggeration control.',\n  'chatterbox-turbo':\n    'Streamlined 350M parameter TTS by Resemble AI. High-quality English speech with less compute and VRAM than larger models.',\n  'tada-1b':\n    'HumeAI TADA 1B — English speech-language model built on Llama 3.2 1B. Generates 700s+ of coherent audio with synchronized text-acoustic alignment.',\n  'tada-3b-ml':\n    'HumeAI TADA 3B Multilingual — built on Llama 3.2 3B. Supports 10 languages with high-fidelity voice cloning via text-acoustic dual alignment.',","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/app/src/components/ServerSettings/ModelManagement.tsx#L33-L69","documentation":"Thrown by fetchHuggingFaceModelInfo() when the Hugging Face public API (huggingface.co/api/models/<repoId>) returns non-2xx. The returned JSON feeds the model-management UI (description, files, download size). It is an unauthenticated client-side fetch, so it inherits HF's rate limits.","triggerScenarios":"GET https://huggingface.co/api/models/<repoId> responds 404 (repo id typo, renamed/gated repo), 401/403 (gated model requiring login), 429 (rate limit), or 5xx. Network failures throw before the status check.","commonSituations":"Hard-coded MODEL_DESCRIPTIONS repo ids drift from real HF repo names after a rename. A model becomes gated and now requires acceptance. Heavy shared-IP usage (CI, NAT) trips HF's 429. A user on a network blocking huggingface.co sees a fetch failure.","solutions":["Verify the repoId string matches an existing public HF repo (check the URL in a browser).","Add a retry with backoff for 429 and 5xx responses.","Fall back to the static MODEL_DESCRIPTIONS entry when the live fetch fails.","For gated models, route the request through an authenticated server-side proxy."],"exampleFix":"// before\nconst response = await fetch(`https://huggingface.co/api/models/${repoId}`);\nif (!response.ok) throw new Error(`Failed to fetch model info: ${response.status}`);\n// after\nconst response = await fetch(`https://huggingface.co/api/models/${repoId}`);\nif (!response.ok) {\n  return { ...MODEL_DESCRIPTIONS[repoId], stale: true } satisfies HuggingFaceModelInfo;\n}","handlingStrategy":"try-catch","validationCode":"const HF_REPO_RE = /^[\\w.-]+\\/[\\w.-]+$/;\nfunction isValidRepoId(repoId: string): boolean {\n  return HF_REPO_RE.test(repoId);\n}","typeGuard":"function isHuggingFaceModelInfo(v: unknown): v is HuggingFaceModelInfo {\n  return typeof v === 'object' && v !== null && ('id' in v || 'siblings' in v || 'modelId' in v);\n}","tryCatchPattern":"try {\n  return await fetchHuggingFaceModelInfo(repoId);\n} catch (e) {\n  // Fall back to the static description rather than crashing the UI.\n  return { ...MODEL_DESCRIPTIONS[repoId], stale: true } as HuggingFaceModelInfo;\n}","preventionTips":["Validate repoId format before fetching.","Fall back to MODEL_DESCRIPTIONS on failure so the UI still renders.","Retry once on 429/5xx before degrading."],"tags":["network","external-api","huggingface","model-management","react","typescript"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}