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
- Edit the file named in the message and change `exclude` to an array: `exclude = ["pattern"]`
- Delete the wrongly typed `exclude` key and rerun the command so it is recreated as an array
- 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
- Always write exclude lists with brackets: exclude = ["pattern"]
- Lint config.toml after manual edits
- Avoid merging [history] sections by string concatenation
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
- [history] in {} is not a table
- aqua var `{}` must be a string, got {}
- backend must be a string or table
- dotfile {target}: encrypt must be a boolean
- expected `run` to be a string or array of strings
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/560176394570f2f2.
Report an issue: GitHub.