{"record":{"id":"fcb1c19cef04657d","repo":"jdx/mise","slug":"expected-run-to-be-a-string-or-array-of-strings","errorCode":null,"errorMessage":"expected `run` to be a string or array of strings","messagePattern":"expected `run` to be a string or array of strings","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/system/hooks.rs","lineNumber":89,"sourceCode":"    pub fn from_toml(phase_raw: &str, value: toml::Value) -> Result<Vec<Self>> {\n        let Some(phase) = BootstrapHookPhase::parse(phase_raw) else {\n            let valid = BootstrapHookPhase::iter()\n                .map(|phase| phase.as_str())\n                .collect::<Vec<_>>();\n            bail!(\n                \"unknown bootstrap hook phase {phase_raw:?}; valid phases are: {}\",\n                valid.join(\", \")\n            );\n        };\n        let runs = match value {\n            toml::Value::String(run) => vec![run],\n            toml::Value::Array(values) => string_array(values, \"expected string commands\")?,\n            toml::Value::Table(mut table) => match table.remove(\"run\") {\n                Some(toml::Value::String(run)) => vec![run],\n                Some(toml::Value::Array(values)) => {\n                    string_array(values, \"expected `run` to contain string commands\")?\n                }\n                Some(_) => bail!(\"expected `run` to be a string or array of strings\"),\n                None => bail!(\"expected a `run` command\"),\n            },\n            _ => bail!(\"expected a string, array of strings, or table with `run`\"),\n        };\n        let hooks = runs\n            .into_iter()\n            .filter_map(|run| {\n                let run = run.trim().to_string();\n                if run.is_empty() {\n                    warn!(\"[bootstrap.hooks.{phase}]: empty command, ignoring entry\");\n                    None\n                } else {\n                    Some(Self { phase, run })\n                }\n            })\n            .collect();\n        Ok(hooks)\n    }","sourceCodeStart":71,"sourceCodeEnd":107,"githubUrl":"https://github.com/jdx/mise/blob/9dcfcaa0dc8747a2577d3270b69bb9d8313b2807/src/system/hooks.rs#L71-L107","documentation":"When a bootstrap hook is written in table form, the table's run key must be a string or an array of strings. This error fires when run exists but is a different TOML type — integer, float, boolean, inline table, etc. mise hooks accept only commands, not structured options objects.","triggerScenarios":"Writing [bootstrap.hooks.final] with run = 3, run = true, or run = { cmd = \"./x.sh\" } — a run key whose TOML type is neither string nor array.","commonSituations":"Porting configs from tools whose hooks take an options object (cmd/args/shell style); pasting booleans or numbers as placeholders; assuming any value is coerced to a string.","solutions":["Set run to a plain command string: run = \"./cleanup.sh\"","Or an array of command strings: run = [\"step1.sh\", \"step2.sh\"]","Remove structured options from run; mise hooks only take command strings"],"exampleFix":"# before\n[bootstrap.hooks.final]\nrun = { cmd = \"./cleanup.sh\" }\n\n# after\n[bootstrap.hooks.final]\nrun = \"./cleanup.sh\"","handlingStrategy":"validation","validationCode":"# TOML tables for hooks must use run as string or array of strings\n# quick check: any run key that is not quoted or a bracketed list of quoted strings\nawk '/^\\[bootstrap\\.hooks\\./ {inhook=1} /^\\[/ && !/bootstrap\\.hooks/ {inhook=0} inhook && /^run[ \\t]*=/ && $0 !~ /run[ \\t]*=[ \\t]*(\"|\\[)/ {print \"bad run value: \" $0}' mise.toml","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Treat hook run as command-only; no options objects","Prefer the string form (run = \"cmd\") unless multiple commands are needed","Validate hook tables with mise bootstrap immediately after editing"],"tags":["mise","bootstrap","hooks","toml","type-mismatch"],"backgroundTag":"config-type-mismatch","analyzedSha":"9dcfcaa0dc8747a2577d3270b69bb9d8313b2807","analyzedAt":"2026-08-17T14:28:50.624Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}