jdx/mise · error

[history] exclude in {} is not an array

Error message

[history] exclude in {} is not an array

What it means

edit_exclude inserts [history] and then a `history.exclude` entry expected to be a TOML array of globs. If `exclude` exists under [history] but is not an array (e.g. `exclude = "node_modules"` or a table), as_array_mut fails and the command bails. This protects the exclude list's expected shape.

Source

Thrown at src/cli/dotfiles/track.rs:483

/// Adds (or removes) a glob in `[history] exclude` of the global config.
/// Returns whether the file changed.
pub(crate) fn edit_exclude(glob: &str, add: bool) -> Result<bool> {
    use toml_edit::{Item, Value};
    let global = crate::config::global_shared_config_path();
    let mut doc = read_document(&global)?;
    let history = doc
        .entry("history")
        .or_insert(Item::Table(toml_edit::Table::new()));
    let Some(table) = history.as_table_mut() else {
        eyre::bail!("[history] in {} is not a table", display_path(&global));
    };
    table.set_implicit(false);
    let exclude = table
        .entry("exclude")
        .or_insert(Item::Value(Value::Array(toml_edit::Array::new())));
    let Some(array) = exclude.as_array_mut() else {
        eyre::bail!(
            "[history] exclude in {} is not an array",
            display_path(&global)
        );
    };
    let present = array.iter().any(|value| value.as_str() == Some(glob));
    let changed = if add && !present {
        array.push(Value::String(toml_edit::Formatted::new(glob.to_string())));
        true
    } else if !add && present {
        array.retain(|value| value.as_str() != Some(glob));
        true
    } else {
        false
    };
    if changed {
        crate::file::write(&global, doc.to_string())?;
    }
    Ok(changed)

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Edit the file named in the message and change `exclude` to an array: `exclude = ["pattern"]`
  2. Delete the wrongly typed `exclude` key and rerun the command so it is recreated as an array
  3. Keep glob lists bracketed when hand-editing [history]

Example fix

// before
[history]
exclude = "*.log"
// after
[history]
exclude = ["*.log"]
Defensive patterns

Strategy: validation

Validate before calling

# ensure history.exclude is an array before running
tomlq '.history.exclude | type' ~/.config/mise/config.toml   # must be "array"

Try / catch

mise dotfiles track --exclude '*.log' || {
  sed -n '/^\[history\]/,/^\[/p' ~/.config/mise/config.toml
}

Prevention

When it happens

Trigger: Adding/removing a dotfiles exclude glob when the global config's [history] section contains `exclude` typed as a string, integer, or inline table instead of an array.

Common situations: User wrote `exclude = "*.log"` instead of `exclude = ["*.log"]`; another tool wrote a table under history.exclude; manual merge turned the array into a value.

Related errors


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/560176394570f2f2. Report an issue: GitHub.