{"record":{"id":"ed369ffe01bb75f2","repo":"jamiepine/voicebox","slug":"current-model-cache-directory-not-found","errorCode":null,"errorMessage":"Current model cache directory not found","messagePattern":"Current model cache directory not found","errorType":"http","errorClass":"HTTPException","httpStatus":404,"severity":"error","filePath":"backend/routes/models.py","lineNumber":130,"sourceCode":"\n@router.get(\"/models/cache-dir\")\nasync def get_models_cache_dir():\n    \"\"\"Get the path to the HuggingFace model cache directory.\"\"\"\n    from huggingface_hub import constants as hf_constants\n\n    return {\"path\": str(Path(hf_constants.HF_HUB_CACHE))}\n\n\n@router.post(\"/models/migrate\")\nasync def migrate_models(request: models.ModelMigrateRequest):\n    \"\"\"Move all downloaded models to a new directory with byte-level progress via SSE.\"\"\"\n    from huggingface_hub import constants as hf_constants\n\n    source = Path(hf_constants.HF_HUB_CACHE)\n    destination = Path(request.destination)\n\n    if not source.exists():\n        raise HTTPException(status_code=404, detail=\"Current model cache directory not found\")\n\n    if source.resolve() == destination.resolve():\n        raise HTTPException(status_code=400, detail=\"Source and destination are the same directory\")\n\n    if destination.resolve().is_relative_to(source.resolve()):\n        raise HTTPException(status_code=400, detail=\"Destination cannot be inside the current cache directory\")\n\n    progress_manager = get_progress_manager()\n    model_dirs = [d for d in source.iterdir() if d.name.startswith(\"models--\") and d.is_dir()]\n    if not model_dirs:\n        progress_manager.update_progress(\"migration\", 1, 1, status=\"complete\")\n        progress_manager.mark_complete(\"migration\")\n        return {\"moved\": 0, \"errors\": [], \"source\": str(source), \"destination\": str(destination)}\n\n    destination.mkdir(parents=True, exist_ok=True)\n\n    same_fs = False\n    try:","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/jamiepine/voicebox/blob/51f49dea198384b4eb6087b72c17057c6eb1c1cd/backend/routes/models.py#L112-L148","documentation":"404 from POST /models/migrate. The endpoint reads HF_HUB_CACHE from huggingface_hub.constants and checks source.exists(); if the configured cache directory does not exist on disk, it raises HTTPException(404, 'Current model cache directory not found'). This typically means HF_HOME/HF_HUB_CACHE points at a path that was never created, was deleted, or lives on an unmounted volume.","triggerScenarios":"POST /models/migrate with any destination body when HF_HUB_CACHE resolves to a non-existent path (e.g. /mnt/models that isn't mounted, or a custom HF_HOME whose cache subdir was never populated).","commonSituations":"Custom HF_HOME/HF_HUB_CACHE env var set but directory not yet created; first run before any model downloaded; cache moved/deleted out of band; container started without the model volume mounted; fresh install where HF_HOME points to a removable drive that's ejected.","solutions":["Run GET /models/cache-dir to see which path the server treats as source, then confirm that directory exists on the host.","If the cache is legitimately empty, create the directory (mkdir -p) or download a model first so HuggingFace creates it.","Correct the HF_HOME / HF_HUB_CACHE env var to point at the real cache location and restart the backend.","If a volume should be mounted there, remount it before retrying migrate."],"exampleFix":"# before — HF_HUB_CACHE points at unmounted path\nGET /models/cache-dir  -> {\"path\": \"/mnt/models\"}  # absent\n# after\nmkdir -p /mnt/models && export HF_HOME=/mnt/models  # then restart backend","handlingStrategy":"validation","validationCode":"async function preflightMigrate(dest: string) {\n  const { path: cacheDir } = await (await fetch('/models/cache-dir')).json();\n  const exists = await checkDirExists(cacheDir); // platform helper or a HEAD on a fs API\n  if (!exists) throw new Error(`Cache directory ${cacheDir} does not exist; set HF_HOME correctly or download a model first.`);\n  return await fetch('/models/migrate', {method:'POST', body: JSON.stringify({destination: dest})});\n}","typeGuard":null,"tryCatchPattern":"try {\n  await fetch('/models/migrate', {method:'POST', body: JSON.stringify({destination})});\n} catch (e) {\n  if (e.response?.status === 404 && /cache directory not found/i.test(e.response.detail)) {\n    // prompt user to fix HF_HOME / mount the volume, then retry\n  } else throw e;\n}","preventionTips":["Before offering 'migrate' in the UI, GET /models/cache-dir and disable the button if the dir is absent.","Ensure the HF_HOME/HF_HUB_CACHE volume is mounted at backend startup.","Download at least one model first so HuggingFace creates the cache directory."],"tags":["models","migration","huggingface","filesystem","http-404","config"],"backgroundTag":null,"analyzedSha":"51f49dea198384b4eb6087b72c17057c6eb1c1cd","analyzedAt":"2026-08-12T16:51:42.824Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}