{"record":{"id":"560176394570f2f2","repo":"jdx/mise","slug":"history-exclude-in-is-not-an-array","errorCode":null,"errorMessage":"[history] exclude in {} is not an array","messagePattern":"\\[history\\] exclude in (.+?) is not an array","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/track.rs","lineNumber":483,"sourceCode":"\n/// Adds (or removes) a glob in `[history] exclude` of the global config.\n/// Returns whether the file changed.\npub(crate) fn edit_exclude(glob: &str, add: bool) -> Result<bool> {\n    use toml_edit::{Item, Value};\n    let global = crate::config::global_shared_config_path();\n    let mut doc = read_document(&global)?;\n    let history = doc\n        .entry(\"history\")\n        .or_insert(Item::Table(toml_edit::Table::new()));\n    let Some(table) = history.as_table_mut() else {\n        eyre::bail!(\"[history] in {} is not a table\", display_path(&global));\n    };\n    table.set_implicit(false);\n    let exclude = table\n        .entry(\"exclude\")\n        .or_insert(Item::Value(Value::Array(toml_edit::Array::new())));\n    let Some(array) = exclude.as_array_mut() else {\n        eyre::bail!(\n            \"[history] exclude in {} is not an array\",\n            display_path(&global)\n        );\n    };\n    let present = array.iter().any(|value| value.as_str() == Some(glob));\n    let changed = if add && !present {\n        array.push(Value::String(toml_edit::Formatted::new(glob.to_string())));\n        true\n    } else if !add && present {\n        array.retain(|value| value.as_str() != Some(glob));\n        true\n    } else {\n        false\n    };\n    if changed {\n        crate::file::write(&global, doc.to_string())?;\n    }\n    Ok(changed)","sourceCodeStart":465,"sourceCodeEnd":501,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/dotfiles/track.rs#L465-L501","documentation":"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.","triggerScenarios":"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.","commonSituations":"User wrote `exclude = \"*.log\"` instead of `exclude = [\"*.log\"]`; another tool wrote a table under history.exclude; manual merge turned the array into a value.","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]"],"exampleFix":"// before\n[history]\nexclude = \"*.log\"\n// after\n[history]\nexclude = [\"*.log\"]","handlingStrategy":"validation","validationCode":"# ensure history.exclude is an array before running\ntomlq '.history.exclude | type' ~/.config/mise/config.toml   # must be \"array\"","typeGuard":null,"tryCatchPattern":"mise dotfiles track --exclude '*.log' || {\n  sed -n '/^\\[history\\]/,/^\\[/p' ~/.config/mise/config.toml\n}","preventionTips":["Always write exclude lists with brackets: exclude = [\"pattern\"]","Lint config.toml after manual edits","Avoid merging [history] sections by string concatenation"],"tags":["config","toml","dotfiles","type-mismatch"],"backgroundTag":"config-type-mismatch","analyzedSha":"afd2eddd3a50c16190efc1c7e94404b48f72af57","analyzedAt":"2026-09-09T01:38:25.179Z","contentChangedAt":"2026-09-09T01:38:25.179Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}