jdx/mise · error

Cannot change version of existing tool stub from

Error message

Cannot change version of existing tool stub from {} to {}

What it means

If a tool stub file already exists at the output path and declares a `version`, `mise generate tool-stub` refuses to regenerate with a different `--version`. The stub's version is treated as immutable on regeneration to avoid silently changing what an existing stub pins; changing it requires removing the existing stub or matching the version.

Solutions

  1. Pass `--version` matching the existing stub's version, or omit regeneration
  2. Delete the existing stub file and regenerate with the new version
  3. Manually edit the `version` field in the stub TOML if intentional

Example fix

// before: existing stub has version = "1.0.0"
mise generate tool-stub --output rg.toml --url ... --version 2.0.0   # bails
// after
delete rg.toml
mise generate tool-stub --output rg.toml --url ... --version 2.0.0
Defensive patterns

Strategy: try-catch

Validate before calling

if (fs.existsSync(outFile)) {
  const existing = TOML.parse(fs.readFileSync(outFile, 'utf8'));
  if (existing.version && wantedVersion && existing.version !== wantedVersion) {
    throw new Error(`delete or align stub: existing ${existing.version} vs wanted ${wantedVersion}`);
  }
}

Try / catch

try {
  await exec(`mise generate tool-stub --output ${out} --version ${v} ...`);
} catch (e) {
  if (String(e).includes('Cannot change version')) {
    fs.rmSync(out);
    await exec(`mise generate tool-stub --output ${out} --version ${v} ...`);
  }
}

Prevention

When it happens

Trigger: Running `mise generate tool-stub` with `--output` pointing at an existing stub file whose TOML `version` field differs from the `--version` argument (including when `--version` is absent and defaults to something else).

Common situations: Re-running generation after a tool released a new version; CI regenerates stubs with a newer pinned version; user forgot the stub already exists with an older pinned version.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of jdx/mise@533346cc37 (2026-09-17). Data as JSON: /api/errors/68c559d4b896c4a5. Report an issue: GitHub.

Appendix: source

Thrown at src/cli/generate/tool_stub.rs:282

            bail!("Either --url or --platform-url must be specified");
        }

        // Read existing file if it exists
        let (existing_content, mut doc) = if self.output.exists() {
            let content = file::read_to_string(&self.output)?;
            let toml_content = extract_toml_from_stub(&content);

            let document = toml_content.parse::<DocumentMut>()?;
            (Some(content), document)
        } else {
            (None, DocumentMut::new())
        };

        // If file exists but we're trying to set a different version, bail
        if existing_content.is_some() && doc.get("version").is_some() {
            let existing_version = doc.get("version").and_then(|v| v.as_str()).unwrap_or("");
            if existing_version != self.version {
                bail!(
                    "Cannot change version of existing tool stub from {} to {}",
                    existing_version,
                    self.version
                );
            }
        }

        // Set or update version only if it's not "latest" (which should be the default)
        if self.version != "latest" {
            doc["version"] = toml_edit::value(&self.version);
        }

        // Get the stub filename (without path)
        let stub_filename = self
            .output
            .file_stem()
            .and_then(|s| s.to_str())
            .unwrap_or("");

View on GitHub (pinned to 533346cc37)