jdx/mise · error · eyre::Report

SwiftPM artifact bundles require a release version; {display

Error message

SwiftPM artifact bundles require a release version; {display_version} selects a Git revision and must be built from source

What it means

SwiftPM artifact bundles are published per release version, so a request that resolves to a Git revision (branch, tag:ref, commit, `ref:...`) can never have one. When bundles are required (artifactbundle = true / artifactbundle_asset set / spm.artifactbundle_only) and the requested version is a git revision, mise aborts instead of pretending to look.

Source

Thrown at src/backend/spm.rs:645

        ToolRequest::Ref { ref_, ref_type, .. } if matches!(ref_type.as_str(), "ref" | "rev") => {
            Some(PackageRevision::Git(ref_.clone()))
        }
        _ => None,
    }
}

fn should_try_artifactbundle(
    revision: &PackageRevision,
    opts: &SpmOptions<'_>,
    mode: ArtifactBundleMode,
    artifactbundle_only: bool,
    display_version: &str,
) -> eyre::Result<bool> {
    if mode == ArtifactBundleMode::SourceOnly && artifactbundle_only {
        bail!("artifactbundle = false conflicts with spm.artifactbundle_only");
    }
    if revision.is_git_revision() && (opts.requires_artifactbundle(mode) || artifactbundle_only) {
        bail!(
            "SwiftPM artifact bundles require a release version; {display_version} selects a Git revision and must be built from source"
        );
    }
    Ok(!revision.is_git_revision() && mode != ArtifactBundleMode::SourceOnly)
}

fn with_install_env(mut command: Expression, tv: &ToolVersion) -> Expression {
    for (key, value) in tv.install_env() {
        command = match value.into_string() {
            Some(value) => command.env(key, value),
            None => command.env_remove(key),
        };
    }
    command
}

/// Restricts `executables` to those listed in `filter_bins`, preserving the
/// original declaration order from `Package.swift` rather than the order in

View on GitHub (pinned to 6f52dcdf99)

Solutions

  1. Pin a real release version (e.g. "1.2.3") so a matching bundle can be selected
  2. Remove the bundle requirement (artifactbundle/artifactbundle_asset) or the spm.artifactbundle_only setting so the git revision builds from source
  3. If you need bundles for unreleased changes, ask upstream to cut a release or build locally without the bundle constraint

Example fix

# before
[tools."spm:foo/bar"]
version = "ref:main"
artifactbundle = true

# after
[tools."spm:foo/bar"]
version = "1.2.3"
artifactbundle = true
Defensive patterns

Strategy: fallback

Validate before calling

case "$version" in ref:*|HEAD|*:main|*:master) echo 'git revision: cannot use with artifactbundle requirement';; esac

Type guard

fn is_git_revision(v: &str) -> bool { v.starts_with("ref:") || v == "HEAD" || v.contains(':') }

Prevention

When it happens

Trigger: `version = "ref:main"` or `version = "HEAD"` on an spm tool that also sets `artifactbundle = true`, or under a global `artifactbundle_only` policy.

Common situations: Tracking a repo's main branch for a fix, or pinning a commit hash, while bundles-only mode is on from a team policy.

Related errors


AI-assisted analysis of jdx/mise@6f52dcdf99 (2026-08-22). Data as JSON: /api/errors/05ce370698316364. Report an issue: GitHub.