{"record":{"id":"c38f3f30e83a034c","repo":"jdx/mise","slug":"config-set-requires-a-toml-config-file-but-is","errorCode":null,"errorMessage":"config set requires a TOML config file, but {} is not TOML","messagePattern":"config set requires a TOML config file, but (.+?) is not TOML","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cli/config/set.rs","lineNumber":124,"sourceCode":"        let file = match self.file {\n            Some(path) => Some(resolve_target_config_path(ConfigPathOptions {\n                path: Some(path),\n                prefer_toml: true,\n                ..Default::default()\n            })?),\n            None if self.global => Some(resolve_target_config_path(ConfigPathOptions {\n                global: true,\n                prefer_toml: true,\n                ..Default::default()\n            })?),\n            None if self.system => Some(system_config_path()),\n            None => top_toml_config(),\n        };\n        let Some(file) = file else {\n            bail!(\"No mise.toml file found\");\n        };\n        if !file.to_string_lossy().ends_with(\".toml\") {\n            bail!(\n                \"config set requires a TOML config file, but {} is not TOML\",\n                display_path(&file)\n            );\n        }\n        if !file.exists() && !self.global && !self.system {\n            bail!(\"config file not found: {}\", display_path(&file));\n        }\n        let raw = match std::fs::read_to_string(&file) {\n            Ok(raw) => raw,\n            Err(error)\n                if (self.global || self.system) && error.kind() == std::io::ErrorKind::NotFound =>\n            {\n                String::new()\n            }\n            Err(error) => return Err(error.into()),\n        };\n        let mut config: toml_edit::DocumentMut = raw.parse()?;\n        let mut container = config.as_item_mut();","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/jdx/mise/blob/afd2eddd3a50c16190efc1c7e94404b48f72af57/src/cli/config/set.rs#L106-L142","documentation":"After resolving the target config file, `mise config set` refuses to write if the resolved file does not end with `.toml`, because set writes TOML. Legacy `.mise` / `.tool-versions` style configs cannot hold arbitrary TOML keys, so mise bails naming the offending path.","triggerScenarios":"`mise config set` resolving to a non-TOML config, e.g. a `.mise` file or `.tool-versions` discovered as the top config, or --file pointing at such a file.","commonSituations":"Projects still using asdf-style `.tool-versions` or the old `.mise` format; passing `--file .tool-versions` to config set.","solutions":["Migrate the config to mise.toml (`mise migrate` / recreate as TOML) and re-run the set","Pass --file pointing at a real mise.toml","Use asdf-compatible commands (e.g. `mise use`) for .tool-versions-managed tools instead of config set","Rename/convert the legacy file to a .toml config"],"exampleFix":"// before\nmise config set --file .tool-versions tools.node 22\n// after\nmise migrate  # converts .tool-versions to mise.toml\nmise config set --file mise.toml tools.node 22","handlingStrategy":"validation","validationCode":"const f = targetFile;\nif (!f.endsWith('.toml')) throw new Error(`config set needs TOML, got ${f}`);","typeGuard":"const isTomlConfig = (p) => p.endsWith('.toml');","tryCatchPattern":null,"preventionTips":["Run `mise migrate` on projects still using .tool-versions or legacy .mise","Only pass .toml files to config set --file","Use `mise use` for asdf-format files instead of config set","Standardize projects on mise.toml"],"tags":["config","toml","file-format"],"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"}