{"record":{"id":"dc2b886816b03ab1","repo":"jdx/mise","slug":"check-shell-must-not-be-empty","errorCode":null,"errorMessage":"Check shell must not be empty","messagePattern":"Check shell must not be empty","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/doctor/project.rs","lineNumber":246,"sourceCode":"    let timeout = check\n        .timeout\n        .as_deref()\n        .map(crate::duration::parse_duration)\n        .transpose()?\n        .unwrap_or(Duration::from_secs(10));\n    if timeout.is_zero() {\n        bail!(\"Check timeout must be greater than zero\");\n    }\n    let mut shell = match &check.shell {\n        Some(shell) => crate::path::split_shell_command(shell)?,\n        None => Settings::get().default_inline_shell()?,\n    };\n    Settings::get().maybe_no_profile(&mut shell);\n    let Some((program, args)) = shell\n        .split_first()\n        .filter(|(program, _)| !program.trim().is_empty())\n    else {\n        bail!(\"Check shell must not be empty\");\n    };\n    CmdLineRunner::new(program)\n        .cmd_body_args(args, &check.run)\n        .current_dir(\n            check\n                .dir\n                .as_ref()\n                .map(|dir| root.join(crate::file::replace_path(dir)))\n                .unwrap_or_else(|| root.to_path_buf()),\n        )\n        .env_clear()\n        .envs(environment)\n        .with_timeout(timeout)\n        .output_isolated(64 * 1024)\n        .await\n}\n\n/// Subscribe to a shutdown signal unless the process inherited it as ignored.","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/doctor/project.rs#L228-L264","documentation":"Each doctor check runs through a shell. The shell comes from the check's `shell` field or the global default_inline_shell setting; after splitting into program+args, if there is no program (empty shell vector) or the program is blank, run_check bails because there is nothing to execute the check command with.","triggerScenarios":"A check with `shell = \"\"` or `shell = \"   \"`, or Settings::get().default_inline_shell() returning an empty/blank-first-element command when no per-check shell is set.","commonSituations":"Setting an empty `shell` in project doctor config; a corrupted or unset default_shell setting (e.g. SHELL env var empty in minimal CI containers) leading to an empty default inline shell.","solutions":["Set an explicit non-empty `shell` on the check, e.g. `shell = \"bash -c\"`.","Fix the default shell setting (check SHELL env var / default_shell setting) so default_inline_shell() yields a real program.","Ensure the shell string contains a program name, not only whitespace."],"exampleFix":"// before\n[[doctor.checks]]\nname = \"build\"\nrun = \"make\"\nshell = \"\"\n\n// after\n[[doctor.checks]]\nname = \"build\"\nrun = \"make\"\nshell = \"bash -c\"","handlingStrategy":"validation","validationCode":"// ensure a shell program is available before running doctor checks\nlet shell = check.shell.clone().or_else(|| std::env::var(\"SHELL\").ok());\nassert!(shell.as_deref().map_or(false, |s| !s.trim().is_empty()));","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set SHELL or the default_shell setting in minimal CI containers.","Prefer an explicit `shell = \"bash -c\"` per check for reproducibility.","Never leave the shell field as an empty string."],"tags":["doctor","shell","validation","cli"],"backgroundTag":"empty-required-field","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}