jdx/mise · error

mas cannot install a pinned version ('{p}')

Error message

mas cannot install a pinned version ('{p}')

What it means

The mas backend cannot install a specific app version: the Mac App Store only serves the latest version of an app. install() rejects any PackageRequest carrying a version pin up front with this error.

Source

Thrown at src/system/packages/mas.rs:257

        }
    }

    async fn unavailable_reason_async(&self) -> Option<String> {
        self.bin().await.err().map(|err| format!("{err:#}"))
    }

    fn supports_version_pins(&self) -> bool {
        false
    }

    async fn installed(&self, pkgs: &[PackageRequest]) -> Result<Vec<PackageStatus>> {
        let apps = mas_list(self.bin().await?).await?;
        Ok(statuses_from_apps(&apps, pkgs))
    }

    async fn install(&self, pkgs: &[PackageRequest], opts: &InstallOpts) -> Result<()> {
        if let Some(p) = pkgs.iter().find(|p| p.version.is_some()) {
            bail!("mas cannot install a pinned version ('{p}')");
        }
        if let Some(p) = pkgs.iter().find(|p| !is_adam_id(&p.name)) {
            bail!("mas install requires a numeric ADAM ID ('{p}'); use `mas search` to find it");
        }
        let mut args = vec!["install".to_string()];
        args.extend(pkgs.iter().map(|p| p.name.clone()));
        if opts.dry_run {
            miseprintln!("mas {}", args.join(" "));
            return Ok(());
        }
        debug!("$ mas {}", args.join(" "));
        let output = tokio::process::Command::new(self.bin().await?)
            .args(&args)
            .stdin(Stdio::null())
            .output()
            .await?;
        if !output.status.success() {
            let stderr = String::from_utf8_lossy(&output.stderr);

View on GitHub (pinned to afd2eddd3a)

Solutions

  1. Remove the version pin so the request contains only the ADAM ID (e.g. `mas:497799835` instead of `mas:497799835:2.1`)
  2. Accept that App Store apps always resolve to the latest available version
  3. If a specific version is required, install it manually via the App Store app or an external mechanism

Example fix

// before
[[packages]]
provider = "mas"
name = "497799835"
version = "2.1.0"
// after
[[packages]]
provider = "mas"
name = "497799835"
# version omitted: mas always installs latest
Defensive patterns

Strategy: validation

Validate before calling

fn assert_no_pin(reqs: &[PackageRequest]) -> Result<()> {
    reqs.iter().find(|p| p.version.is_some())
        .map_or(Ok(()), |p| Err(eyre!("mas cannot pin versions: {p}")))
}

Try / catch

if let Err(e) = provider.install(&pkgs, &opts).await {
    if e.to_string().contains("pinned version") {
        eprintln!("retrying without version pins");
        let unpinned: Vec<_> = pkgs.iter().map(|p| p.without_version()).collect();
        provider.install(&unpinned, &opts).await?;
    } else { return Err(e); }
}

Prevention

When it happens

Trigger: Calling the mas package provider's install (via mise packages/tool config) with any request whose `version` field is Some, e.g. `mas@1234567:1.2.3` or a lockfile/mise.toml declaring a pinned version for an ADAM ID.

Common situations: Porting a package config from brew/cargo-style tools to mas; a lockfile generated from another machine pinned a version; users expecting App Store apps to be version-pinnable like casks.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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