{"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":534,"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":516,"sourceCodeEnd":552,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/dotfiles/track.rs#L516-L552","documentation":"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.","triggerScenarios":"Global config contains `[history] exclude = \"some-glob\"` (string) or `exclude = { ... }` (table) when a track/untrack command tries to append/remove an exclude glob.","commonSituations":"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.","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"],"exampleFix":"// before (config.toml)\n[history]\nexclude = \"*.log\"\n// after (config.toml)\n[history]\nexclude = [\"*.log\"]","handlingStrategy":"validation","validationCode":"awk '/^exclude/{ if ($0 !~ /\\[/) print \"history.exclude must be an array\" }' \"${MISE_GLOBAL_CONFIG:-$HOME/.config/mise/config.toml}\"","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["dotfiles","toml","config","type-mismatch"],"backgroundTag":"config-type-mismatch","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}