{"id":"baf3909074959563","repo":"rust-lang/cargo","slug":"crate-name-is-empty","errorCode":null,"errorMessage":"crate name is empty","messagePattern":"crate name is empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/bin/cargo/commands/install.rs","lineNumber":272,"sourceCode":"type CrateVersion = (String, Option<VersionReq>);\n\nfn parse_crate(krate: &str) -> crate::CargoResult<CrateVersion> {\n    let (krate, version) = if let Some((k, v)) = krate.split_once('@') {\n        if k.is_empty() {\n            // by convention, arguments starting with `@` are response files\n            anyhow::bail!(\"missing crate name before '@'\");\n        }\n        let krate = k.to_owned();\n        let version = Some(parse_semver_flag(v)?);\n        (krate, version)\n    } else {\n        let krate = krate.to_owned();\n        let version = None;\n        (krate, version)\n    };\n\n    if krate.is_empty() {\n        anyhow::bail!(\"crate name is empty\");\n    }\n\n    Ok((krate, version))\n}\n\n/// Parses x.y.z as if it were =x.y.z, and gives CLI-specific error messages in the case of invalid\n/// values.\nfn parse_semver_flag(v: &str) -> CargoResult<VersionReq> {\n    // If the version begins with character <, >, =, ^, ~ parse it as a\n    // version range, otherwise parse it as a specific version\n    let first = v\n        .chars()\n        .next()\n        .ok_or_else(|| format_err!(\"no version provided for the `--version` flag\"))?;\n\n    if let Some(stripped) = v.strip_prefix(\"v\") {\n        bail!(\n            \"the version provided, `{v}` is not a valid SemVer requirement\\n\\n\\","sourceCodeStart":254,"sourceCodeEnd":290,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/bin/cargo/commands/install.rs#L254-L290","documentation":"From parse_crate (src/bin/cargo/commands/install.rs:271-273). After handling the `@` split, if the resulting crate name is empty (e.g. the whole spec was empty or reduced to nothing), it bails. Guards against an empty package name reaching PackageName validation.","triggerScenarios":"`cargo install \"\"` or a spec that reduces to empty after stripping (e.g. stray quotes/whitespace producing an empty token).","commonSituations":"Shell quoting bug producing an empty argument; a script variable that expanded to empty; copy-paste leaving an empty crate slot.","solutions":["Provide a non-empty crate name: `cargo install <crate>`.","Check the shell variable/expansion feeding the command isn't empty.","Remove stray quotes around an empty value."],"exampleFix":"# before\nCRATE=\"\"\ncargo install \"$CRATE\"\n\n# after\nCRATE=ripgrep\ncargo install \"$CRATE\"","handlingStrategy":"validation","validationCode":"// Reject empty crate names before invoking cargo install\nfn nonempty_crate(s: &str) -> Result<&str, String> {\n    let t = s.trim();\n    if t.is_empty() { Err(\"crate name is empty\".into()) } else { Ok(t) }\n}","typeGuard":"fn is_nonempty_crate_name(s: &str) -> bool {\n    !s.trim().is_empty()\n}","tryCatchPattern":null,"preventionTips":["Validate crate-name shell variables are non-empty before use.","Quote variables and fail fast in scripts when a required arg is missing."],"tags":["cargo","install","validation","cli"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}