{"record":{"id":"fe271c9beec3e145","repo":"jdx/mise","slug":"collection-updates-require-scalar-or-array-values","errorCode":null,"errorMessage":"collection updates require scalar or array values","messagePattern":"collection updates require scalar or array values","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/config/set.rs","lineNumber":253,"sourceCode":"        } else {\n            table.insert(last_key, value);\n        }\n\n        let raw = config.to_string();\n        MiseToml::from_str(&raw, &file)?;\n        if let Some(parent) = file.parent() {\n            std::fs::create_dir_all(parent)?;\n        }\n        std::fs::write(&file, raw)?;\n        Ok(())\n    }\n}\n\nfn values(item: toml_edit::Item) -> eyre::Result<Vec<toml_edit::Value>> {\n    match item {\n        toml_edit::Item::Value(toml_edit::Value::Array(array)) => Ok(array.into_iter().collect()),\n        toml_edit::Item::Value(value) => Ok(vec![value]),\n        _ => bail!(\"collection updates require scalar or array values\"),\n    }\n}\n\nfn values_equal(left: &toml_edit::Value, right: &toml_edit::Value) -> bool {\n    if let (Some(left), Some(right)) = (left.as_str(), right.as_str()) {\n        return left == right;\n    }\n    if let (Some(left), Some(right)) = (left.as_integer(), right.as_integer()) {\n        return left == right;\n    }\n    if let (Some(left), Some(right)) = (left.as_float(), right.as_float()) {\n        return left == right;\n    }\n    if let (Some(left), Some(right)) = (left.as_bool(), right.as_bool()) {\n        return left == right;\n    }\n    if let (Some(left), Some(right)) = (left.as_datetime(), right.as_datetime()) {\n        return left == right;","sourceCodeStart":235,"sourceCodeEnd":271,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/cli/config/set.rs#L235-L271","documentation":"`mise config` append/remove operations read the current value of a key as a collection to modify. The `values` helper accepts only a TOML array or a single scalar value; anything else — notably an inline table or nested structure — cannot be treated as a collection, so mise bails. Array-of-tables (nested table items) also fall into the rejected arm.","triggerScenarios":"`mise config append <key> <item>` / `mise config remove <key> <item>` where the existing key holds a table/inline-table (e.g. `[tools.node]` section or an array of tables `[[env._]]`), rather than a scalar or plain array.","commonSituations":"Trying to append to a key whose value is a nested table like `env.FOO.detail = ...`; appending to `[[some.table]]` array-of-tables entries; scripts assuming every config value is a list.","solutions":["Only use append/remove on scalar or array-valued keys; edit table-valued keys by targeting their leaf scalar/array sub-keys","Edit the nested table directly in mise.toml or via `mise config set <table>.<subkey> <value>`","Restructure the config so the collection is a plain array instead of array-of-tables if collection ops are needed","Use `mise config get <key>` first to inspect the value's shape before appending"],"exampleFix":"// before\n$ mise config append env._ foo   # env._ is an array-of-tables -> rejected\n// after\n$ mise config set env.FILE /path/to/env   # target the scalar sub-key of the table","handlingStrategy":"type-guard","validationCode":"v=$(mise config get \"$key\" 2>/dev/null); case \"$v\" in ''|'['*|\"\\\"\"*|*.*.) ;; *) echo \"$key is not scalar/array\"; exit 1;; esac","typeGuard":"is_scalar_or_array() { v=$(mise config get \"$1\" 2>/dev/null); case \"$v\" in \"[\"*|\"\\\"\"*|\"'\"*|[0-9]*|true|false) return 0;; *) return 1;; esac; }","tryCatchPattern":"mise config append \"$key\" \"$item\" 2>&1 | grep -q 'scalar or array' && { echo \"edit the table sub-keys of $key directly\"; exit 1; }","preventionTips":["Inspect the value with `mise config get <key>` before append/remove","Use append/remove only on scalar/array keys","Restructure tables into flat arrays when collection operations are needed","Target leaf sub-keys of tables instead of the table itself"],"tags":["config","toml","collection","cli"],"backgroundTag":"unsupported-operation","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"}