unslothai/unsloth · error · HTTPException

Invalid model snapshot repository ID.

Error message

Invalid model snapshot repository ID.

What it means

Raised as a 400 by the model-config endpoint when the optional model_snapshot_repo_id query/body parameter, after stripping whitespace, fails the shared hub validator is_valid_repo_id (imported from hub.utils.paths). Namespace-less ids like 'gpt2' are valid, so the check is the shared validator rather than a strict namespace regex — but malformed ids (bad characters, empty-ish segments, bad separators) are rejected.

Source

Thrown at studio/backend/routes/models.py:2311

        )

        local_model = is_local_path(model_name)
        if not local_model:
            model_name = resolve_cached_repo_id_case(model_name)
        scan_target = model_name
        exact_snapshot_path = (
            model_snapshot_path.strip()
            if isinstance(model_snapshot_path, str) and model_snapshot_path.strip()
            else None
        )
        exact_snapshot_repo_id = model_name
        if isinstance(model_snapshot_repo_id, str):
            snapshot_repo_id = model_snapshot_repo_id.strip()
            # Namespace-less Hub ids like "gpt2" are valid, so use the shared validator, not the regex.
            from hub.utils.paths import is_valid_repo_id as _shared_is_valid_repo_id

            if snapshot_repo_id and not _shared_is_valid_repo_id(snapshot_repo_id):
                raise HTTPException(
                    status_code = 400,
                    detail = "Invalid model snapshot repository ID.",
                )
            if snapshot_repo_id:
                exact_snapshot_repo_id = snapshot_repo_id
        if local_model:
            normalized_model_name = normalize_path(model_name)
            try:
                scan_target = str(Path(normalized_model_name).expanduser().resolve(strict = False))
            except (OSError, RuntimeError, ValueError):
                scan_target = normalized_model_name
        if exact_snapshot_path and not local_model:
            exact_snapshot_repo_id = resolve_cached_repo_id_case(exact_snapshot_repo_id)
            scan_target = _model_config_inspection_target(
                exact_snapshot_repo_id,
                True,
                normalize_path(exact_snapshot_path),
            )

View on GitHub (pinned to 203007d190)

Solutions

  1. Send a well-formed Hub repo id such as 'org/repo-name' or a namespace-less 'gpt2' — no scheme, no absolute path, no spaces.
  2. Trim whitespace client-side before sending (the server strips, but embedded bad characters still fail).
  3. If you meant a local path, pass it via the local-path/local_model parameters instead of model_snapshot_repo_id.

Example fix

# before
client.get('/api/models/config/MyModel', params={'model_snapshot_repo_id': 'C:\models\MyModel'})  # 400

# after
client.get('/api/models/config/MyModel', params={'model_snapshot_repo_id': 'org/my-model'})
Defensive patterns

Strategy: type-guard

Validate before calling

const REPO_ID_RE = /^[\w.-]+(\/[\w.-]+)?$/;
function isValidRepoId(v: string | undefined): v is string {
  return typeof v === 'string' && REPO_ID_RE.test(v.trim()) && v.trim().length > 0;
}
if (snapshotRepoId !== undefined && !isValidRepoId(snapshotRepoId)) {
  throw new Error('model_snapshot_repo_id must be a Hub repo id like org/repo or gpt2');
}

Type guard

function isValidRepoId(v: unknown): v is string {
  return typeof v === 'string'
    && /^[\w.-]+(\/[\w.-]+)?$/.test(v.trim())
    && !v.trim().startsWith('/')
    && !v.trim().endsWith('/');
}

Try / catch

try {
  cfg = client.get(url, params=params)
except HTTPError as e:
    if e.response.status_code == 400 and 'repository ID' in e.response.json()['detail']:
        params.pop('model_snapshot_repo_id')  # retry with the model_name default
        cfg = client.get(url, params=params)
    else: raise

Prevention

When it happens

Trigger: GET /api/models/config/... with model_snapshot_repo_id containing invalid characters (spaces, backslashes), malformed separators, leading/trailing slashes after strip(), or a repo id shape the shared validator rejects.

Common situations: Front-end passing a local filesystem path where a Hub repo id is expected; copy-paste artifacts (whitespace, unicode dashes); case/format drift after a Hub rename.

Related errors


AI-assisted analysis of unslothai/unsloth@203007d190 (2026-08-15). Data as JSON: /api/errors/ee4b498d22083372. Report an issue: GitHub.