{"record":{"id":"c9ff9247b7e0b1ce","repo":"unslothai/unsloth","slug":"invalid-repo-id-format","errorCode":null,"errorMessage":"Invalid repo_id format","messagePattern":"Invalid repo_id format","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"studio/backend/hub/services/datasets/cache_inventory.py","lineNumber":540,"sourceCode":"    return sorted(seen_lower.values(), key = lambda c: c[\"repo_id\"])\n\n\nasync def list_cached_datasets_response() -> dict:\n    \"\"\"List dataset repos already downloaded into the HF cache.\"\"\"\n    try:\n        return {\"cached\": await asyncio.to_thread(_scan_hf_dataset_caches)}\n    except Exception as exc:\n        logger.error(\"Error listing cached datasets: %s\", exc, exc_info = True)\n        raise HTTPException(\n            status_code = 500,\n            detail = \"Failed to read the local dataset cache.\",\n        ) from exc\n\n\nasync def delete_cached_dataset_response(repo_id: str, cache_path: Optional[str] = None) -> dict:\n    \"\"\"Remove a cached dataset repo from the HF cache.\"\"\"\n    if not _is_valid_repo_id(repo_id):\n        raise HTTPException(status_code = 400, detail = \"Invalid repo_id format\")\n\n    repo_key = await asyncio.to_thread(resolve_cached_repo_id_case, repo_id, repo_type = \"dataset\")\n    if not downloads.registry.begin_delete(repo_key):\n        raise HTTPException(\n            status_code = 400,\n            detail = \"Cancel the active download before deleting.\",\n        )\n    try:\n        return await asyncio.to_thread(_delete_cached_dataset_blocking, repo_key, cache_path)\n    finally:\n        downloads.registry.end_delete(repo_key)\n        hf_cache_scan.invalidate_hf_cache_scans()\n\n\ndef _delete_cached_dataset_blocking(repo_id: str, cache_path: Optional[str] = None) -> dict:\n    scans, _seen_roots = _collect_hf_cache_scans()\n    app_entry = app_processed_dataset_cache_from_path(repo_id, cache_path) if cache_path else None\n","sourceCodeStart":522,"sourceCodeEnd":558,"githubUrl":"https://github.com/unslothai/unsloth/blob/203007d19051dcd2ae33876786d117c99f6b0368/studio/backend/hub/services/datasets/cache_inventory.py#L522-L558","documentation":"HTTPException 400 raised by delete_cached_dataset_response when the repo_id argument fails _is_valid_repo_id — the basic HF id format check (namespace/name with allowed characters). The delete is rejected before any cache lookup or destructive action.","triggerScenarios":"Calling the cached-dataset delete endpoint with a repo_id that is not a well-formed HF id: empty string, leading/trailing slashes, double slashes, invalid characters, or an overlong namespace/name segment.","commonSituations":"Frontend forwarding an untrimmed input; URL-decoding artifacts injecting %2F or spaces; users pasting full HF URLs instead of the id.","solutions":["Send a properly formatted repo id like 'username/dataset-name' (or a bare name for no-namespace repos).","Trim whitespace and strip any leading '#' or URL prefix before calling the API.","Validate with the same pattern client-side: ^[\\w.-]+(/[\\w.-]+)?$ style check."],"exampleFix":"# before\nrequests.delete(api + \"/datasets/%20user%2Fmodel%2F\")  # 400 Invalid repo_id format\n\n# after\nrepo_id = \"user/model\".strip().strip(\"/\")\nrequests.delete(api + f\"/datasets/{repo_id}\")","handlingStrategy":"validation","validationCode":"import re\n\n_REPO_ID_RE = re.compile(r\"^[\\w.-]+(?:/[\\w.-]+)?$\")\n\ndef normalize_repo_id(raw: str) -> str:\n    rid = raw.strip().strip(\"/\")\n    rid = rid.replace(\"https://huggingface.co/\", \"\").replace(\"http://huggingface.co/\", \"\")\n    if not _REPO_ID_RE.fullmatch(rid):\n        raise ValueError(f\"Invalid repo_id format: {raw!r}\")\n    return rid","typeGuard":"def is_valid_repo_id(repo_id: str) -> bool:\n    import re\n    return bool(re.fullmatch(r\"[\\w.-]+(?:/[\\w.-]+)?\", repo_id.strip()))","tryCatchPattern":"import httpx\n\nresp = httpx.delete(f\"{api}/hub/datasets/{repo_id}\")\nif resp.status_code == 400 and \"Invalid repo_id format\" in resp.text:\n    repo_id = normalize_repo_id(repo_id)\n    resp = httpx.delete(f\"{api}/hub/datasets/{repo_id}\")","preventionTips":["Trim and validate repo ids client-side with the same format rules.","Send repo ids, never full HF URLs, to cache endpoints.","Reject empty or whitespace-only ids at the form level."],"tags":["hf-cache","datasets","input-validation","http-400"],"backgroundTag":null,"analyzedSha":"203007d19051dcd2ae33876786d117c99f6b0368","analyzedAt":"2026-08-15T02:48:39.846Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}