{"id":"32deb7e5dfcf6a20","repo":"rust-lang/cargo","slug":"invalid-character-in-package-name-toolchai-32deb7","errorCode":null,"errorMessage":"invalid character `+` in package name: `+{toolchain}`\n    Use `cargo +{toolchain} update` if you meant to use the `{toolchain}` toolchain.","messagePattern":"invalid character `\\+` in package name: `\\+(.+?)`\n    Use `cargo \\+(.+?) update` if you meant to use the `(.+?)` toolchain\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/bin/cargo/commands/update.rs","lineNumber":76,"sourceCode":"        ))\n}\n\npub fn exec(gctx: &mut GlobalContext, args: &ArgMatches) -> CliResult {\n    let mut ws = args.workspace(gctx)?;\n\n    if args.is_present_with_zero_values(\"package\") {\n        print_available_packages(&ws)?;\n    }\n\n    let to_update = if args.contains_id(\"package\") {\n        \"package\"\n    } else {\n        \"package2\"\n    };\n    let to_update = values(args, to_update);\n    for crate_name in to_update.iter() {\n        if let Some(toolchain) = crate_name.strip_prefix(\"+\") {\n            return Err(anyhow!(\n                \"invalid character `+` in package name: `+{toolchain}`\n    Use `cargo +{toolchain} update` if you meant to use the `{toolchain}` toolchain.\"\n            )\n            .into());\n        }\n    }\n\n    let update_opts = UpdateOptions {\n        recursive: args.flag(\"recursive\"),\n        precise: args.get_one::<String>(\"precise\").map(String::as_str),\n        to_update,\n        dry_run: args.dry_run(),\n        workspace: args.flag(\"workspace\"),\n        gctx,\n    };\n\n    if args.flag(\"breaking\") {\n        gctx.cli_unstable()","sourceCodeStart":58,"sourceCodeEnd":94,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/bin/cargo/commands/update.rs#L58-L94","documentation":"In `cargo update` (update.rs:74-81), each package name is checked for a leading `+`. A leading `+` is how Cargo selects a toolchain (e.g. `cargo +nightly`), so a package name starting with `+` almost always means the user misplaced the toolchain selector after `update` instead of before `cargo`.","triggerScenarios":"Running `cargo update +nightly` (toolchain after the subcommand) instead of `cargo +nightly update`. The `+nightly` is interpreted as a package name and fails this check.","commonSituations":"Confusing toolchain-selector argument order; scripts that append `+toolchain` to the wrong position; copying rustup examples incorrectly.","solutions":["Move the toolchain selector before the subcommand: `cargo +nightly update`.","If you really have a package whose name starts with `+`, that is not a valid crate name — rename it.","Remove the `+toolchain` token if you did not intend to override the toolchain."],"exampleFix":"// before\n$ cargo update +nightly\nerror: invalid character `+` in package name: `+nightly`\n\n// after\n$ cargo +nightly update","handlingStrategy":"validation","validationCode":"for name in &packages {\n    if let Some(rest) = name.strip_prefix('+') {\n        eprintln!(\"did you mean `cargo +{rest} update`? moving toolchain before subcommand\");\n        return;\n    }\n}","typeGuard":"fn is_toolchain_misplacement(arg: &str) -> bool {\n    arg.starts_with('+') && arg[1..].chars().all(|c| c.is_alphanumeric() || c == '-')\n}\n","tryCatchPattern":null,"preventionTips":["Remember rustup toolchain order: `cargo +<toolchain> <subcommand>`.","Validate package args don't start with '+' before passing to cargo."],"tags":["cargo","update","toolchain","rustup","cli"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}