jdx/mise · error
[history] exclude in
Error message
[history] exclude in {} is not an array What it means
In edit_exclude(), after ensuring the `[history]` table, the code gets/creates `history.exclude` and expects it to be a TOML array of globs. If `exclude` exists but is not an array (e.g. a string or table), it bails with the file path rather than clobbering the existing value.
Solutions
- Edit the reported file to make exclude an array: `exclude = ["glob1", "glob2"]`
- If a single glob was intended, wrap it in brackets
- Re-run the dot track/untrack command afterwards
Example fix
// before (config.toml) [history] exclude = "*.log" // after (config.toml) [history] exclude = ["*.log"]
Defensive patterns
Strategy: validation
Validate before calling
awk '/^exclude/{ if ($0 !~ /\[/) print "history.exclude must be an array" }' "${MISE_GLOBAL_CONFIG:-$HOME/.config/mise/config.toml}" Prevention
- Write history.exclude as a TOML array of strings, never a bare string
- Validate TOML types with a linter after editing the global config
- Prefer `mise settings` commands over hand-editing when available
When it happens
Trigger: Global config contains `[history] exclude = "some-glob"` (string) or `exclude = { ... }` (table) when a track/untrack command tries to append/remove an exclude glob.
Common situations: User wrote exclude as a single quoted string instead of an array; config generated by another tool with different shape; manual merge of config files producing wrong type.
Related errors
- [history] in is not a table
- backend must be a string or table
- dotfile : encrypt must be a boolean
- [dotfiles]." ": mode symlink-each requires a directory…
- expected `run` to be a string or array of strings
AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17).
Data as JSON: /api/errors/560176394570f2f2.
Report an issue: GitHub.
Appendix: source
Thrown at src/cli/dotfiles/track.rs:534
/// 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 533346cc37)