{"record":{"id":"00698e0272c63f2a","repo":"rust-lang/mdBook","slug":"shell-name-missing","errorCode":null,"errorMessage":"Shell name missing.","messagePattern":"Shell name missing\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/main.rs","lineNumber":36,"sourceCode":"fn main() {\n    init_logger();\n\n    let command = create_clap_command();\n\n    // Check which subcommand the user ran...\n    let res = match command.get_matches().subcommand() {\n        Some((\"init\", sub_matches)) => cmd::init::execute(sub_matches),\n        Some((\"build\", sub_matches)) => cmd::build::execute(sub_matches),\n        Some((\"clean\", sub_matches)) => cmd::clean::execute(sub_matches),\n        #[cfg(feature = \"watch\")]\n        Some((\"watch\", sub_matches)) => cmd::watch::execute(sub_matches),\n        #[cfg(feature = \"serve\")]\n        Some((\"serve\", sub_matches)) => cmd::serve::execute(sub_matches),\n        Some((\"test\", sub_matches)) => cmd::test::execute(sub_matches),\n        Some((\"completions\", sub_matches)) => (|| {\n            let shell = sub_matches\n                .get_one::<Shell>(\"shell\")\n                .ok_or_else(|| anyhow!(\"Shell name missing.\"))?;\n\n            let mut complete_app = create_clap_command();\n            clap_complete::generate(\n                *shell,\n                &mut complete_app,\n                \"mdbook\",\n                &mut std::io::stdout().lock(),\n            );\n            Ok(())\n        })(),\n        _ => unreachable!(),\n    };\n\n    if let Err(e) = res {\n        utils::log_backtrace(&e);\n\n        std::process::exit(101);\n    }","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/rust-lang/mdBook/blob/dc21064fc21d955a0e1f67e65e336883c3e5260b/src/main.rs#L18-L54","documentation":"mdbook's `completions` subcommand reads the shell type from the `shell` argument via `ArgMatches::get_one::<Shell>(\"shell\")`. If the value is absent from the parsed matches, the code raises this anyhow error instead of panicking on an Option unwrap. In practice clap's required-argument definition makes this nearly unreachable; it is a defensive guard.","triggerScenarios":"Running `mdbook completions` without providing the required shell argument in a way that bypasses clap's validation — e.g. invoking the closure logic programmatically with hand-built or empty ArgMatches, or a clap definition change removing `.required(true)` / possible values from the `shell` arg.","commonSituations":"Programmatic re-use of the completions branch with constructed ArgMatches; downgrading or patching mdbook where the `shell` arg constraint changed; scripted invocations that strip arguments.","solutions":["Pass the shell argument explicitly: `mdbook completions bash` (or zsh/fish/powershell/elvish).","Check shell completion script installation docs; most shells source `mdbook completions <shell>` output once.","If invoking internally, build matches through `create_clap_command().get_matches()` rather than hand-crafting ArgMatches.","Verify no shell alias/wrapper is dropping the argument."],"exampleFix":"// before (hand-built matches, missing arg)\nlet matches = Command::new(\"completions\").get_matches_from([\"mdbook\"]);\n// after\nlet matches = Command::new(\"completions\")\n    .arg(Arg::new(\"shell\").required(true))\n    .get_matches_from([\"mdbook\", \"completions\", \"bash\"]);","handlingStrategy":"validation","validationCode":"if sub_matches.get_one::<Shell>(\"shell\").is_none() {\n    eprintln!(\"usage: mdbook completions <bash|zsh|fish|powershell|elvish>\");\n    std::process::exit(2);\n}","typeGuard":null,"tryCatchPattern":"let shell = sub_matches\n    .get_one::<Shell>(\"shell\")\n    .ok_or_else(|| anyhow!(\"Shell name missing.\"))?; // propagate instead of unwrap","preventionTips":["Always pass the shell argument to `mdbook completions`.","Keep the `shell` arg defined with `.required(true)` in create_clap_command.","Build ArgMatches through the real clap Command, not by hand.","Add a CI test that runs `mdbook completions bash` end-to-end."],"tags":["cli","clap","missing-argument","completions"],"backgroundTag":"missing-required-cli-argument","analyzedSha":"dc21064fc21d955a0e1f67e65e336883c3e5260b","analyzedAt":"2026-09-01T10:15:12.134Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T15:18:49.778Z"}