jdx/mise · error

version_order must be "source" or "semver"

Error message

version_order must be "source" or "semver"

What it means

While parsing a registry TOML entry, mise's parse_registry_tool only accepts version_order = "source" (order versions as the backend reports them, the default when the key is absent) or version_order = "semver" (sort with semver semantics). Any other string — including different casing like "Semver" — causes an immediate bail with this message. The value controls how mise orders a tool's versions when resolving 'latest'.

Source

Thrown at src/registry.rs:371

fn parse_registry_tool(short: &str, value: &toml::Value) -> Result<(RegistryTool, bool)> {
    let table = value
        .as_table()
        .ok_or_else(|| eyre::eyre!("registry tool must be a TOML table"))?;
    let backends = table
        .get("backends")
        .and_then(toml::Value::as_array)
        .ok_or_else(|| eyre::eyre!("backends must be an array"))?
        .iter()
        .map(parse_registry_backend)
        .collect::<Result<Vec<_>>>()?;
    ensure!(!backends.is_empty(), "backends must not be empty");

    let missing_version_order = !table.contains_key("version_order");
    let version_order = match table.get("version_order").and_then(toml::Value::as_str) {
        Some("source") => VersionOrder::Source,
        Some("semver") => VersionOrder::Semver,
        Some(_) => bail!("version_order must be \"source\" or \"semver\""),
        None => VersionOrder::Source,
    };

    let aliases = string_array(table.get("aliases"), "aliases")?;
    let bins = string_array(table.get("bins"), "bins")?;
    let overrides = string_array(table.get("overrides"), "overrides")?;
    let os = string_array(table.get("os"), "os")?;
    let idiomatic_files = parse_registry_idiomatic_files(table.get("idiomatic_files"))?;
    let detect = string_array(table.get("detect"), "detect")?;
    let description = table
        .get("description")
        .map(|value| {
            value
                .as_str()
                .map(|value| leak_string(value.to_string()))
                .ok_or_else(|| eyre::eyre!("description must be a string"))
        })
        .transpose()?;

View on GitHub (pinned to 9dcfcaa0dc)

Solutions

  1. Set version_order = "source" if the backend already returns newest-first versions (most common), or version_order = "semver" only for strictly semver tools.
  2. Delete the version_order key entirely — the default is Source, which is usually what you want.
  3. Re-run `cargo test registry` (or the registry validation task) to confirm the entry parses.
  4. Check for invisible issues: the match is exact and case-sensitive, so verify no quotes/whitespace/casing drift.

Example fix

# before
[tools]
mytool = "1.2.3"
version_order = "date"
# after
version_order = "source"
Defensive patterns

Strategy: validation

Validate before calling

# validate version_order before submitting a registry entry
order=$(tomlq -r '.version_order // "source"' registry/mytool.toml)
[ "$order" = "source" ] || [ "$order" = "semver" ] || { echo "bad version_order: $order" >&2; exit 1; }

Type guard

fn is_valid_version_order(v: &str) -> bool { v == "source" || v == "semver" }

Prevention

When it happens

Trigger: Adding or editing a file in registry/ (or a custom registry) with e.g. version_order = "date", "natural", "SemVer", or "semver " (trailing whitespace). Parsing runs when the registry is loaded at startup or when running registry validation/tests, and the whole registry load fails.

Common situations: Contributing a new tool to mise's registry and guessing a version_order value; copy-pasting an entry from another registry that supports richer ordering; changing casing during a refactor.

Related errors


AI-assisted analysis of jdx/mise@9dcfcaa0dc (2026-08-17). Data as JSON: /api/errors/6ca5d2ea9a694cb4. Report an issue: GitHub.