jdx/mise · error

{message}

Error message

{message}

What it means

string_array validates array-form hook values: every element must be a TOML string. The message is supplied by the caller, so it reads either 'expected string commands' (bare array under [bootstrap.hooks]) or 'expected `run` to contain string commands' (run = [...] in table form). It fires when the array mixes in an integer, float, boolean, table, or nested array.

Source

Thrown at src/system/hooks.rs:115

                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)
    }
}

fn string_array(values: Vec<toml::Value>, message: &str) -> Result<Vec<String>> {
    let mut out = vec![];
    for value in values {
        match value {
            toml::Value::String(s) => out.push(s),
            _ => bail!("{message}"),
        }
    }
    Ok(out)
}

pub async fn run_phase(
    hooks: &[BootstrapHook],
    phase: BootstrapHookPhase,
    dry_run: bool,
) -> Result<()> {
    let phase_hooks: Vec<_> = hooks.iter().filter(|hook| hook.phase == phase).collect();
    if phase_hooks.is_empty() {
        return Ok(());
    }
    info!("bootstrap: {phase} hooks");
    let shell = Settings::get().default_inline_shell()?;
    let Some((program, shell_args)) = shell.split_first() else {
        bail!("default inline shell args must not be empty");

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Quote every element so the array is all strings
  2. Fold numeric flags into the command string itself ("npm ci --silent", not ["npm ci", 2])
  3. Re-run mise bootstrap to confirm parsing

Example fix

# before
[bootstrap.hooks]
post-tools = ["npm ci", 2]

# after
[bootstrap.hooks]
post-tools = ["npm ci --silent"]
Defensive patterns

Strategy: validation

Validate before calling

python3 - <<'EOF'
import tomllib,sys
c=tomllib.load(open('mise.toml','rb'))
for phase,v in (c.get('bootstrap',{}).get('hooks',{}) or {}).items():
    items = v if isinstance(v,list) else v.get('run',[]) if isinstance(v,dict) else []
    if isinstance(items,list) and any(not isinstance(i,str) for i in items):
        sys.exit(f'hook phase {phase} has non-string array element')
EOF

Prevention

When it happens

Trigger: Writing [bootstrap.hooks] post-tools = ["npm ci", 2] or [bootstrap.hooks.final] run = [true, "echo done"] — any hook array containing a non-string element.

Common situations: Putting numeric options or exit codes into command lists; heterogeneous arrays produced by templating; assuming TOML coerces values like YAML-style tooling does.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/a9f7cc933b76914e. Report an issue: GitHub.