jdx/mise · error
expected `run` to be a string or array of strings
Error message
expected `run` to be a string or array of strings
What it means
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.
Source
Thrown at src/system/hooks.rs:89
pub fn from_toml(phase_raw: &str, value: toml::Value) -> Result<Vec<Self>> {
let Some(phase) = BootstrapHookPhase::parse(phase_raw) else {
let valid = BootstrapHookPhase::iter()
.map(|phase| phase.as_str())
.collect::<Vec<_>>();
bail!(
"unknown bootstrap hook phase {phase_raw:?}; valid phases are: {}",
valid.join(", ")
);
};
let runs = match value {
toml::Value::String(run) => vec![run],
toml::Value::Array(values) => string_array(values, "expected string commands")?,
toml::Value::Table(mut table) => match table.remove("run") {
Some(toml::Value::String(run)) => vec![run],
Some(toml::Value::Array(values)) => {
string_array(values, "expected `run` to contain string commands")?
}
Some(_) => bail!("expected `run` to be a string or array of strings"),
None => bail!("expected a `run` command"),
},
_ => bail!("expected a string, array of strings, or table with `run`"),
};
let hooks = runs
.into_iter()
.filter_map(|run| {
let run = run.trim().to_string();
if run.is_empty() {
warn!("[bootstrap.hooks.{phase}]: empty command, ignoring entry");
None
} else {
Some(Self { phase, run })
}
})
.collect();
Ok(hooks)
}View on GitHub (pinned to 9dcfcaa0dc)
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
Example fix
# before
[bootstrap.hooks.final]
run = { cmd = "./cleanup.sh" }
# after
[bootstrap.hooks.final]
run = "./cleanup.sh" Defensive patterns
Strategy: validation
Validate before calling
# TOML tables for hooks must use run as string or array of strings
# quick check: any run key that is not quoted or a bracketed list of quoted strings
awk '/^\[bootstrap\.hooks\./ {inhook=1} /^\[/ && !/bootstrap\.hooks/ {inhook=0} inhook && /^run[ \t]*=/ && $0 !~ /run[ \t]*=[ \t]*("|\[)/ {print "bad run value: " $0}' mise.toml Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- expected a string, array of strings, or table with `run`
- {message}
- unknown bootstrap hook phase {phase_raw:?}; valid phases are
- expected a `run` command
- backend must be a string or table
AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17).
Data as JSON: /api/errors/fcb1c19cef04657d.
Report an issue: GitHub.