jamiepine/voicebox · warning · HTTPException
Destination cannot be inside the current cache directory
Error message
Destination cannot be inside the current cache directory
What it means
400 from POST /models/migrate. Using Path.is_relative_to, the route rejects a destination whose resolved path is nested inside the resolved source. Moving the cache into itself would create recursive copies or move the directory into a child that gets moved along with it, corrupting the cache layout. Checked after the same-directory guard.
Source
Thrown at backend/routes/models.py:136
return {"path": str(Path(hf_constants.HF_HUB_CACHE))}
@router.post("/models/migrate")
async def migrate_models(request: models.ModelMigrateRequest):
"""Move all downloaded models to a new directory with byte-level progress via SSE."""
from huggingface_hub import constants as hf_constants
source = Path(hf_constants.HF_HUB_CACHE)
destination = Path(request.destination)
if not source.exists():
raise HTTPException(status_code=404, detail="Current model cache directory not found")
if source.resolve() == destination.resolve():
raise HTTPException(status_code=400, detail="Source and destination are the same directory")
if destination.resolve().is_relative_to(source.resolve()):
raise HTTPException(status_code=400, detail="Destination cannot be inside the current cache directory")
progress_manager = get_progress_manager()
model_dirs = [d for d in source.iterdir() if d.name.startswith("models--") and d.is_dir()]
if not model_dirs:
progress_manager.update_progress("migration", 1, 1, status="complete")
progress_manager.mark_complete("migration")
return {"moved": 0, "errors": [], "source": str(source), "destination": str(destination)}
destination.mkdir(parents=True, exist_ok=True)
same_fs = False
try:
same_fs = source.stat().st_dev == destination.stat().st_dev
except OSError:
pass
async def migrate_background():
moved = 0View on GitHub (pinned to 51f49dea19)
Solutions
- Pick a destination that is a sibling or on a different volume, not a child of the cache.
- GET /models/cache-dir and confirm your destination is not under that path (after resolving symlinks).
- If you need a backup, copy the cache elsewhere first, then point migrate at the external copy.
- Clean up any stray subdirectories created by a prior failed migration attempt before retrying.
Example fix
# before — destination inside cache
curl -X POST http://localhost:8000/models/migrate -d '{"destination":"/Users/me/.cache/huggingface/archive"}'
# after
curl -X POST http://localhost:8000/models/migrate -d '{"destination":"/Volumes/External/hf-cache"}' Defensive patterns
Strategy: validation
Validate before calling
import { resolve, relative, isAbsolute } from 'path';
async function migrateTo(dest: string) {
const { path: cacheDir } = await (await fetch('/models/cache-dir')).json();
const rel = relative(resolve(cacheDir), resolve(dest));
if (isAbsolute(rel) || (!rel.startsWith('..') && rel !== '')) {
throw new Error('Destination is inside the cache directory');
}
return await fetch('/models/migrate', {method:'POST', body: JSON.stringify({destination: dest})});
} Try / catch
try {
await fetch('/models/migrate', {method:'POST', body: JSON.stringify({destination})});
} catch (e) {
if (e.response?.status === 400 && /inside the current cache/i.test(e.response.detail)) {
// suggest a sibling or external volume
} else throw e;
} Prevention
- Pick a destination outside the cache tree (sibling or other volume).
- GET /models/cache-dir and reject nested destinations in the UI before submit.
- Resolve symlinks in the destination before the comparison.
When it happens
Trigger: POST /models/migrate with destination like '/current/cache/subdir' or '/current/cache/.backup' — anything where destination.resolve() lives under source.resolve(). Also triggers when destination is a symlink whose target is inside the cache.
Common situations: User tries to 'make a backup folder inside the cache'; UI suggests a default destination nested under the cache root; migration retry pointing at a partially-created subdir from a prior failed run; symlink inside cache pointing deeper inside.
Related errors
- Source and destination are the same directory
- Unknown model: {model_name}
- Current model cache directory not found
- Unknown model: {request.model_name}
- Model ${model_size} is not downloaded yet. Use /generate to
AI-assisted analysis of jamiepine/voicebox@51f49dea19 (2026-08-12).
Data as JSON: /api/errors/1de9e5eae54bd254.
Report an issue: GitHub.