{"record":{"id":"28dc9b40b77ea727","repo":"aaif-goose/goose","slug":"invalid-model-spec-expected-format-user-rep","errorCode":null,"errorMessage":"Invalid model spec '{}': expected format 'user/repo:quantization'","messagePattern":"Invalid model spec '(.+?)': expected format 'user/repo:quantization'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-local-inference/src/hf_models.rs","lineNumber":739,"sourceCode":"        .map(|s| {\n            let quantization = parse_quantization(&s.rfilename);\n            let download_url = build_download_url(repo_id, &s.rfilename);\n            HfGgufFile {\n                filename: s.rfilename,\n                size_bytes: s.size.unwrap_or(0),\n                quantization,\n                download_url,\n            }\n        })\n        .collect();\n\n    Ok(files)\n}\n\n/// Parse a model spec like \"bartowski/Llama-3.2-1B-Instruct-GGUF:Q4_K_M\" into (repo_id, quantization).\npub fn parse_model_spec(spec: &str) -> Result<(String, String)> {\n    let (repo_id, quant) = spec.rsplit_once(':').ok_or_else(|| {\n        anyhow::anyhow!(\n            \"Invalid model spec '{}': expected format 'user/repo:quantization'\",\n            spec\n        )\n    })?;\n\n    if !repo_id.contains('/') {\n        bail!(\"Invalid repo_id '{}': expected format 'user/repo'\", repo_id);\n    }\n\n    if quant.is_empty() {\n        bail!(\n            \"Invalid model spec '{}': expected format 'user/repo:quantization'\",\n            spec\n        );\n    }\n\n    Ok((repo_id.to_string(), quant.to_string()))\n}","sourceCodeStart":721,"sourceCodeEnd":757,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-local-inference/src/hf_models.rs#L721-L757","documentation":"parse_model_spec splits the spec with rsplit_once(':') into (repo_id, quantization). This error fires when there is no colon at all, and - with the same message from the follow-up check - when the quantization after the colon is empty. A separate 'Invalid repo_id' error covers a left side lacking '/'. It is the entry validation for resolve_model_spec_full and the GGUF download path.","triggerScenarios":"Calling resolve_model_spec_full (directly or via resolve_local_model_selection / resolve_gguf_model) with 'owner/repo' lacking the ':Q4_K_M' suffix, or with a trailing colon 'owner/repo:'.","commonSituations":"User-facing model strings typed without the quantization; configs migrated from a format that stored repo and quant separately; trailing-colon strings produced by naive format!(\"{}:{}\", repo, variant) with an empty variant.","solutions":["Append the quantization suffix, e.g. 'bartowski/Llama-3.2-1B-Instruct-GGUF:Q4_K_M'","Pick a quantization that actually exists in the repo (check the repo's .gguf file list) to avoid the downstream 'No GGUF file with quantization' error","If building the spec programmatically, validate both halves are non-empty before formatting"],"exampleFix":"// before\nlet spec = format!(\"{}:{}\", repo_id, variant_id); // variant_id may be None/empty\nlet (repo, quant) = parse_model_spec(&spec)?;\n\n// after\nlet variant = variant_id.context(\"quantization variant required\")?;\nanyhow::ensure!(!variant.is_empty(), \"quantization variant required\");\nlet (repo, quant) = parse_model_spec(&format!(\"{}:{}\", repo_id, variant))?;","handlingStrategy":"validation","validationCode":"// reject bad specs before touching the network\nfn spec_ok(spec: &str) -> bool {\n    matches!(spec.rsplit_once(':'), Some((repo, q)) if repo.contains('/') && !q.is_empty())\n}\nanyhow::ensure!(spec_ok(&spec), \"model spec must be 'owner/repo:QUANT', got '{spec}'\");","typeGuard":"fn is_valid_model_spec(spec: &str) -> bool {\n    match spec.rsplit_once(':') {\n        Some((repo, quant)) => repo.contains('/') && !quant.is_empty(),\n        None => false,\n    }\n}","tryCatchPattern":"match parse_model_spec(&spec) {\n    Err(e) if e.to_string().contains(\"expected format 'user/repo:quantization'\") => {\n        // prompt the user for the quantization instead of retrying the same string\n    }\n    other => other,\n}","preventionTips":["Validate the 'owner/repo:QUANT' shape at config load, not at download time","When building specs dynamically, ensure both halves are non-empty before formatting","Offer the repo's real quantization list in the UI so users cannot invent one"],"tags":["rust","validation","huggingface","gguf","parsing"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}