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

  1. Migrate the config to mise.toml (`mise migrate` / recreate as TOML) and re-run the set
  2. Pass --file pointing at a real mise.toml
  3. Use asdf-compatible commands (e.g. `mise use`) for .tool-versions-managed tools instead of config set
  4. 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

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


AI-assisted analysis of jdx/mise@afd2eddd3a (2026-09-09). Data as JSON: /api/errors/c38f3f30e83a034c. Report an issue: GitHub.