jdx/mise · error · eyre::Report

invalid system package spec: expected

Error message

invalid system package spec: expected '<manager>:<package>[@version]'

What it means

For the mas (Mac App Store) manager, package names ending in '@latest' are special-cased: after stripping the '@latest' suffix the remaining name must be non-empty, otherwise the spec is meaningless and mise bails.

Solutions

  1. Provide the numeric ADAM ID, e.g. mas:497799835
  2. Remove the '@latest' suffix and specify the app ID directly
  3. Drop the entry if no specific app is intended

Example fix

// before
mise bootstrap packages use mas:@latest
// after
mise bootstrap packages use mas:497799835
Defensive patterns

Strategy: validation

Validate before calling

function masSpecOk(spec) {
  const name = spec.split(":")[1] ?? "";
  return !(name === "@latest" || name === "");
}

Prevention

When it happens

Trigger: Passing 'mas:@latest' to normalize_use_spec_package_name — a mas spec whose name is exactly '@latest' with no ADAM ID.

Common situations: Template or scripted spec generation that omits the app ID; misunderstanding that mas supports 'latest' as a version for an unnamed app.

Understand the failure class

Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.

Related errors


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

Appendix: source

Thrown at src/system/mod.rs:1872

        [token] if !token.is_empty() => Some(format!("homebrew/cask/{token}")),
        _ => None,
    }
}

fn is_brew_manager(mgr: &str) -> bool {
    matches!(mgr, "brew" | "brew-cask")
}

fn is_opaque_package_manager(mgr: &str) -> bool {
    is_brew_manager(mgr) || matches!(mgr, "mas" | "nix")
}

fn normalize_use_spec_package_name<'a>(mgr: &str, name: &'a str) -> eyre::Result<&'a str> {
    if mgr == "mas"
        && let Some(name) = name.strip_suffix("@latest")
    {
        if name.is_empty() {
            bail!("invalid system package spec: expected '<manager>:<package>[@version]'");
        }
        return Ok(name);
    }
    Ok(name)
}

fn validate_package_name(mgr: &str, name: &str) -> eyre::Result<()> {
    if mgr == "nix" {
        packages::nix::Installable::parse(name)?;
    }
    if mgr == "mas" && !packages::mas::is_adam_id(name) {
        bail!("mas app IDs must be numeric ADAM IDs (e.g. \"mas:497799835\")");
    }
    Ok(())
}

/// Collect export declarations before manager validation can warn and skip an
/// invalid entry. Export must either represent the entire selection or fail.

View on GitHub (pinned to 533346cc37)