{"record":{"id":"930892138c8c560e","repo":"jdx/mise","slug":"artifactbundle-asset-must-end-with-artifactbundle","errorCode":null,"errorMessage":"artifactbundle_asset must end with .artifactbundle.zip, got {name}","messagePattern":"artifactbundle_asset must end with \\.artifactbundle\\.zip, got (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/backend/spm.rs","lineNumber":929,"sourceCode":"                        })\n                        .collect()\n                })\n        }\n    };\n    let Some(assets) = assets else {\n        return Ok(None);\n    };\n    select_artifactbundle_asset(assets, opts)\n}\n\nfn select_artifactbundle_asset(\n    assets: Vec<ArtifactBundleReleaseAsset>,\n    opts: &SpmOptions<'_>,\n) -> eyre::Result<Option<ArtifactBundleReleaseAsset>> {\n    let artifactbundle_asset = opts.artifactbundle_asset(None);\n    if let Some(name) = artifactbundle_asset {\n        if !is_artifactbundle_zip(&name) {\n            bail!(\"artifactbundle_asset must end with .artifactbundle.zip, got {name}\");\n        }\n        return assets\n            .into_iter()\n            .find(|a| a.name == name)\n            .map(Some)\n            .ok_or_else(|| {\n                eyre::eyre!(\"artifactbundle_asset not found in release assets: {name}\")\n            });\n    }\n\n    let candidates = assets\n        .into_iter()\n        .filter(|a| is_artifactbundle_zip(&a.name))\n        .collect::<Vec<_>>();\n    match candidates.len() {\n        0 => Ok(None),\n        1 => Ok(candidates.into_iter().next()),\n        _ => bail!(","sourceCodeStart":911,"sourceCodeEnd":947,"githubUrl":"https://github.com/jdx/mise/blob/533346cc374382b41ec5ff70536252b2e96e725c/src/backend/spm.rs#L911-L947","documentation":"When the user pins a specific artifact bundle via the artifactbundle_asset option, select_artifactbundle_asset validates the name format. A custom asset name must end with .artifactbundle.zip (the SwiftPM artifact bundle zip convention); anything else is rejected as invalid configuration.","triggerScenarios":"resolve_artifactbundle_asset calls select_artifactbundle_asset with opts.artifactbundle_asset(None) returning Some(name) where is_artifactbundle_zip(&name) is false — e.g. artifactbundle_asset = 'swiftlint.zip' or 'bundle.artifactbundle'.","commonSituations":"Typo in the configured asset name, using the unzipped bundle name, or pointing at a checksum/other release asset instead of the bundle zip.","solutions":["Set artifactbundle_asset to the exact release asset name ending in .artifactbundle.zip","Copy the asset name verbatim from the release's assets page","Remove artifactbundle_asset to let mise auto-select among bundles"],"exampleFix":"// before (mise.toml)\n[tools.swiftlint]\nversion = '0.54.0'\nartifactbundle_asset = 'swiftlint-macos.zip'\n// after\n[tools.swiftlint]\nversion = '0.54.0'\nartifactbundle_asset = 'swiftlint.artifactbundle.zip'","handlingStrategy":"validation","validationCode":"// validate the configured name before install\nname=\"$ARTIFACTBUNDLE_ASSET\"; case \"$name\" in *.artifactbundle.zip) :;; *) echo \"invalid: $name\";; esac","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Copy asset names verbatim from the GitHub release","Remember the required suffix: .artifactbundle.zip"],"tags":["swiftpm","config","asset-name","validation"],"backgroundTag":"invalid-config-value","analyzedSha":"533346cc374382b41ec5ff70536252b2e96e725c","analyzedAt":"2026-09-17T13:35:38.149Z","contentChangedAt":"2026-09-17T13:35:38.149Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}