jdx/mise · error

multiple SwiftPM artifact bundles found

Error message

multiple SwiftPM artifact bundles found: {}. Set artifactbundle_asset to choose one

What it means

SwiftPM backend asset selection found more than one *.artifactbundle.zip in a GitHub release and no explicit choice was made. Because mise cannot safely guess which bundle matches the platform, it stops and asks the user to disambiguate via the artifactbundle_asset tool option.

Solutions

  1. Set artifactbundle_asset in the tool config to the exact bundle name for your platform
  2. Ask upstream to merge platform variants into a single multi-variant artifact bundle
  3. Pin a different version that ships one unambiguous bundle

Example fix

// before
[tools.swiftformat]
version = '0.53.0'
// after
[tools.swiftformat]
version = '0.53.0'
artifactbundle_asset = 'swiftformat-linux-x86_64.artifactbundle.zip'
Defensive patterns

Strategy: validation

Validate before calling

// count candidate bundles and pre-choose one
gh release view <tag> -R <owner>/<repo> --json assets -q '[.assets[].name | select(endswith(".artifactbundle.zip"))] | length'

Prevention

When it happens

Trigger: select_artifactbundle_asset filters the release assets with is_artifactbundle_zip, finds 2+ candidates, and bails listing their names.

Common situations: A project publishing separate bundles per platform/arch (e.g. one for macOS arm64, one for linux x86_64) without embedding platform-specific variant directories in a single bundle.

Related errors


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

Appendix: source

Thrown at src/backend/spm.rs:947

            bail!("artifactbundle_asset must end with .artifactbundle.zip, got {name}");
        }
        return assets
            .into_iter()
            .find(|a| a.name == name)
            .map(Some)
            .ok_or_else(|| {
                eyre::eyre!("artifactbundle_asset not found in release assets: {name}")
            });
    }

    let candidates = assets
        .into_iter()
        .filter(|a| is_artifactbundle_zip(&a.name))
        .collect::<Vec<_>>();
    match candidates.len() {
        0 => Ok(None),
        1 => Ok(candidates.into_iter().next()),
        _ => bail!(
            "multiple SwiftPM artifact bundles found: {}. Set artifactbundle_asset to choose one",
            candidates
                .into_iter()
                .map(|a| a.name)
                .collect::<Vec<_>>()
                .join(", ")
        ),
    }
}

fn is_artifactbundle_zip(name: &str) -> bool {
    name.to_lowercase().ends_with(".artifactbundle.zip")
}

#[derive(Debug, Deserialize)]
struct SwiftTargetInfo {
    target: SwiftTarget,
}

View on GitHub (pinned to 533346cc37)