jdx/mise · error

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

Error message

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

What it means

When normalizing `mas` (Mac App Store) use-specs, normalize_use_spec_package_name strips a '@latest' suffix from the package name. If stripping leaves an empty name (spec was effectively 'mas:@latest'), it bails because there is no actual package identifier left.

Source

Thrown at src/system/mod.rs:1566

    } else {
        name.rsplit_once('/').map(|(tap, _)| tap)
    }
}

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

fn is_opaque_package_manager(mgr: &str) -> bool {
    is_brew_manager(mgr) || mgr == "mas"
}

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 == "mas" && !packages::mas::is_adam_id(name) {
        bail!("mas app IDs must be numeric ADAM IDs (e.g. \"mas:497799835\")");
    }
    Ok(())
}

pub(crate) fn brew_taps_from_config(config: &Config) -> IndexMap<String, String> {
    brew_taps_from_config_files(&config.config_files)
}

fn brew_taps_from_config_files(config_files: &ConfigMap) -> IndexMap<String, String> {

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Supply the app ID or name: "mas:497799835" or "mas:Xcode"
  2. Drop '@latest' — mas specs don't need it; just use "mas:<app-id>"
  3. Fix templates/variables in your config that produced an empty package name

Example fix

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

Strategy: validation

Validate before calling

// For mas specs, a non-empty package id must precede any @latest suffix:
function isValidMasSpec(spec: string): boolean {
  if (!spec.startsWith("mas:")) return true;
  const name = spec.slice(4).replace(/@latest$/, "");
  return name.length > 0;
}
// isValidMasSpec("mas:@latest") === false; isValidMasSpec("mas:497799835") === true

Type guard

function hasMasPackageName(spec: string): boolean {
  if (!spec.startsWith("mas:")) return true;
  return spec.slice(4).replace(/@latest$/, "").length > 0;
}

Try / catch

try {
  await mise(["bootstrap", "packages", "use", spec]);
} catch (e) {
  if (String(e).includes("invalid system package spec")) {
    throw new Error(`mas needs an app id, e.g. mas:497799835 (got "${spec}")`);
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling `mise bootstrap packages use mas:@latest` (or a config entry resolving to that), i.e. the mas manager with '@latest' as the version but no package name/id before it.

Common situations: Hand-writing a Mac App Store entry and omitting the numeric app ID or app name; templating gone wrong where the package variable was empty; misunderstanding that mas requires an app ID (e.g. mas:497799835 for Xcode).

Understand the failure class

Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.

Related errors


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