{"record":{"id":"1127c5b173c37347","repo":"jdx/mise","slug":"history-in-is-not-a-table","errorCode":null,"errorMessage":"[history] in {} is not a table","messagePattern":"\\[history\\] in (.+?) is not a table","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/dotfiles/track.rs","lineNumber":527,"sourceCode":"\n    $ <bold>mise dot track ~/.zshrc ~/.config/hypr</bold>\n    $ <bold>mise dot track ~/.zshrc --os macos</bold>\n    $ <bold>mise dot track ~/.config/app/credentials --encrypt</bold>\n    $ <bold>mise dot track ~/.config/app/state.json --no-autosave</bold>\n\"#\n);\n\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","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/dotfiles/track.rs#L509-L545","documentation":"edit_exclude() edits the `[history]` table in the global shared config to add/remove an exclude glob. If the file contains a top-level `history` key whose value is not a TOML table (e.g. a string or array), the code refuses to silently overwrite it and bails with the offending file path.","triggerScenarios":"Running `mise dot track`/`untrack` flows that update excludes against a global config where `history` is defined as a non-table value, e.g. `history = \"off\"` or `history = []`.","commonSituations":"Hand-edited or AI-generated config with wrong TOML shape; a config written by an older/different tool that used a scalar for history; copy-paste mistakes in config.toml.","solutions":["Open the reported global config file and change `history` to a table: `[history]`","Remove the invalid scalar `history` key and let mise recreate `[history] exclude`","Validate the TOML (e.g. with a TOML linter) after editing"],"exampleFix":"// before (config.toml)\nhistory = \"disabled\"\n// after (config.toml)\n[history]\nenabled = false","handlingStrategy":"validation","validationCode":"grep -E '^history[[:space:]]*=' \"${MISE_GLOBAL_CONFIG:-$HOME/.config/mise/config.toml}\" && echo 'history must be a [history] table, not a scalar — fix before dot track'","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always define history settings under a [history] table in TOML","Validate config files with a TOML parser after hand edits","Never set `history = <scalar>` in the global config"],"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"}