jdx/mise · error
config set requires a TOML config file, but {} is not TOML
Error message
config set requires a TOML config file, but {} is not TOML What it means
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.
Source
Thrown at src/cli/config/set.rs:124
let file = match self.file {
Some(path) => Some(resolve_target_config_path(ConfigPathOptions {
path: Some(path),
prefer_toml: true,
..Default::default()
})?),
None if self.global => Some(resolve_target_config_path(ConfigPathOptions {
global: true,
prefer_toml: true,
..Default::default()
})?),
None if self.system => Some(system_config_path()),
None => top_toml_config(),
};
let Some(file) = file else {
bail!("No mise.toml file found");
};
if !file.to_string_lossy().ends_with(".toml") {
bail!(
"config set requires a TOML config file, but {} is not TOML",
display_path(&file)
);
}
if !file.exists() && !self.global && !self.system {
bail!("config file not found: {}", display_path(&file));
}
let raw = match std::fs::read_to_string(&file) {
Ok(raw) => raw,
Err(error)
if (self.global || self.system) && error.kind() == std::io::ErrorKind::NotFound =>
{
String::new()
}
Err(error) => return Err(error.into()),
};
let mut config: toml_edit::DocumentMut = raw.parse()?;
let mut container = config.as_item_mut();View on GitHub (pinned to afd2eddd3a)
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
Example fix
// before mise config set --file .tool-versions tools.node 22 // after mise migrate # converts .tool-versions to mise.toml mise config set --file mise.toml tools.node 22
Defensive patterns
Strategy: validation
Validate before calling
const f = targetFile;
if (!f.endsWith('.toml')) throw new Error(`config set needs TOML, got ${f}`); Type guard
const isTomlConfig = (p) => p.endsWith('.toml'); Prevention
- 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
When it happens
Trigger: `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.
Common situations: Projects still using asdf-style `.tool-versions` or the old `.mise` format; passing `--file .tool-versions` to config set.
Related errors
- failed to parse registry option {k} as a TOML value: {e}
- aqua var `{}` must be a string, got {}
- Type not found
- collection updates require scalar or array values
- [history] in {} is not a table
AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09).
Data as JSON: /api/errors/c38f3f30e83a034c.
Report an issue: GitHub.