{"record":{"id":"b25f2791d359417e","repo":"jamiepine/voicebox","slug":"unknown-model-request-model-name","errorCode":null,"errorMessage":"Unknown model: {request.model_name}","messagePattern":"Unknown model: (.+?)","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"warning","filePath":"backend/routes/models.py","lineNumber":400,"sourceCode":"                    size_mb=None,\n                    loaded=loaded,\n                )\n            )\n\n    return models.ModelStatusListResponse(models=statuses)\n\n\n@router.post(\"/models/download\")\nasync def trigger_model_download(request: models.ModelDownloadRequest):\n    \"\"\"Trigger download of a specific model.\"\"\"\n    from ..backends import get_model_config, get_model_load_func\n\n    task_manager = get_task_manager()\n    progress_manager = get_progress_manager()\n\n    config = get_model_config(request.model_name)\n    if not config:\n        raise HTTPException(status_code=400, detail=f\"Unknown model: {request.model_name}\")\n\n    load_func = get_model_load_func(config)\n\n    async def download_in_background():\n        try:\n            result = load_func()\n            if asyncio.iscoroutine(result):\n                await result\n            task_manager.complete_download(request.model_name)\n        except Exception as e:\n            task_manager.error_download(request.model_name, str(e))\n\n    task_manager.start_download(request.model_name)\n\n    progress_manager.update_progress(\n        model_name=request.model_name,\n        current=0,\n        total=0,","sourceCodeStart":382,"sourceCodeEnd":418,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/models.py#L382-L418","documentation":"400 from POST /models/download. The body is ModelDownloadRequest{model_name}; get_model_config(request.model_name) returns None when the id isn't in the registry, so the route raises HTTPException(400, f'Unknown model: {request.model_name}'). This is the same registry lookup used by unload/delete, so an unknown id fails identically across all three operations.","triggerScenarios":"POST /models/download {\"model_name\":\"qwen3\"} (incomplete id); {\"model_name\":\"Qwen3-1.7B\"} (wrong case); typo like 'qwen3-1.7B' or 'qwen-1.7b'; a model_name that exists in the UI but isn't registered for the current backend_type.","commonSituations":"Client used display_name or free text instead of the registry id; backend_type (mlx vs pytorch) doesn't expose that model; version skew between frontend model list and backend registry; user typed a repo id ('Qwen/Qwen3-1.7B') instead of the local model_name.","solutions":["GET /models/status and copy the exact model_name (lowercase id like qwen3-1.7b, whisper-turbo, etc.).","Send that id verbatim in the JSON body: {\"model_name\":\"qwen3-1.7b\"}.","If the model isn't listed at all for your backend_type, switch backend or pick a supported equivalent.","Keep the client's model list in sync with the server registry — don't hard-code ids."],"exampleFix":"# before\ncurl -X POST http://localhost:8000/models/download -d '{\"model_name\":\"Qwen3-1.7B\"}'\n# after\ncurl -X POST http://localhost:8000/models/download -d '{\"model_name\":\"qwen3-1.7b\"}'","handlingStrategy":"validation","validationCode":"async function knownModel(name: string) {\n  const status = await (await fetch('/models/status')).json();\n  return status.models.some(m => m.model_name === name);\n}\nif (!(await knownModel(req.model_name))) {\n  throw new Error(`Unknown model: ${req.model_name}`);\n}\nawait fetch('/models/download', {method:'POST', body: JSON.stringify({model_name: req.model_name})});","typeGuard":null,"tryCatchPattern":"try {\n  await fetch('/models/download', {method:'POST', body: JSON.stringify({model_name})});\n} catch (e) {\n  if (e.response?.status === 400 && /Unknown model/.test(e.response.detail)) {\n    // refresh status list, fix id, offer valid options to user\n  } else throw e;\n}","preventionTips":["Populate the download UI from GET /models/status so only valid ids are offered.","Copy model_name verbatim (lowercase, hyphenated) — never use display_name or repo_id.","Invalidate cached id lists when backend_type changes."],"tags":["models","download","registry","validation","http-400"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}