{"id":"42e6f867b55eb589","repo":"rust-lang/cargo","slug":"missing-crate-name-before","errorCode":null,"errorMessage":"missing crate name before '@'","messagePattern":"missing crate name before '@'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/bin/cargo/commands/install.rs","lineNumber":260,"sourceCode":"            krates,\n            source,\n            from_cwd,\n            &compile_opts,\n            args.flag(\"force\"),\n            args.flag(\"no-track\"),\n            args.dry_run(),\n        )?;\n    }\n    Ok(())\n}\n\ntype 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","sourceCodeStart":242,"sourceCodeEnd":278,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/bin/cargo/commands/install.rs#L242-L278","documentation":"From parse_crate (src/bin/cargo/commands/install.rs:256-269). It splits a crate spec on the first `@`; if the part before `@` is empty (the argument starts with `@`), it bails. By convention arguments starting with `@` are response files, so an empty crate name before `@` is treated as a user error rather than silently consuming a response file.","triggerScenarios":"`cargo install @1.2.3` (intending crate@version but omitting the name), or any spec where `@` is the first character.","commonSituations":"Typing the version-first form; forgetting the crate name; intending a response file (e.g. @args.txt) where Cargo install doesn't support response files for the crate position.","solutions":["Put the crate name before `@`: `cargo install <crate>@<version>`.","If you meant a response file, note `cargo install` crate args don't support `@file` syntax there; pass versions via --version.","Use `--version <ver>` instead of the `@version` shorthand."],"exampleFix":"// before\ncargo install @1.2.3\n\n// after\ncargo install ripgrep@1.2.3   # or: cargo install ripgrep --version 1.2.3","handlingStrategy":"validation","validationCode":"// Ensure a crate@version spec has a non-empty name before the @\nfn parse_crate_spec(s: &str) -> Option<(&str, Option<&str>)> {\n    match s.split_once('@') {\n        Some((name, ver)) if !name.is_empty() => Some((name, Some(ver))),\n        Some(_) => None, // missing name before @\n        None => Some((s, None)),\n    }\n}","typeGuard":"fn has_crate_name_before_at(s: &str) -> bool {\n    match s.find('@') {\n        Some(0) => false,\n        _ => true,\n    }\n}","tryCatchPattern":null,"preventionTips":["Always write `<crate>@<version>`, never `@<version>` alone.","Prefer the --version flag when only the version matters."],"tags":["cargo","install","version","cli","argument-parsing"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}