{"record":{"id":"18dde676d779f798","repo":"jdx/mise","slug":"artifactbundle-false-conflicts-with-spm-artifact","errorCode":null,"errorMessage":"artifactbundle = false conflicts with spm.artifactbundle_only","messagePattern":"artifactbundle = false conflicts with spm\\.artifactbundle_only","errorType":"validation","errorClass":"eyre::Report","httpStatus":null,"severity":"error","filePath":"src/backend/spm.rs","lineNumber":642,"sourceCode":"\nfn package_revision(tv: &ToolVersion) -> Option<PackageRevision> {\n    match &tv.request {\n        ToolRequest::Ref { ref_, ref_type, .. } if matches!(ref_type.as_str(), \"ref\" | \"rev\") => {\n            Some(PackageRevision::Git(ref_.clone()))\n        }\n        _ => None,\n    }\n}\n\nfn should_try_artifactbundle(\n    revision: &PackageRevision,\n    opts: &SpmOptions<'_>,\n    mode: ArtifactBundleMode,\n    artifactbundle_only: bool,\n    display_version: &str,\n) -> eyre::Result<bool> {\n    if mode == ArtifactBundleMode::SourceOnly && artifactbundle_only {\n        bail!(\"artifactbundle = false conflicts with spm.artifactbundle_only\");\n    }\n    if revision.is_git_revision() && (opts.requires_artifactbundle(mode) || artifactbundle_only) {\n        bail!(\n            \"SwiftPM artifact bundles require a release version; {display_version} selects a Git revision and must be built from source\"\n        );\n    }\n    Ok(!revision.is_git_revision() && mode != ArtifactBundleMode::SourceOnly)\n}\n\nfn with_install_env(mut command: Expression, tv: &ToolVersion) -> Expression {\n    for (key, value) in tv.install_env() {\n        command = match value.into_string() {\n            Some(value) => command.env(key, value),\n            None => command.env_remove(key),\n        };\n    }\n    command\n}","sourceCodeStart":624,"sourceCodeEnd":660,"githubUrl":"https://github.com/jdx/mise/blob/6f52dcdf99e282ef7a7db68c81301fa4618d0f79/src/backend/spm.rs#L624-L660","documentation":"should_try_artifactbundle rejects a combination where the per-tool option says `artifactbundle = false` (SourceOnly) while the global `spm.artifactbundle_only` setting demands bundles for every spm install. The two directives contradict each other, so mise fails fast instead of guessing which wins.","triggerScenarios":"A global `[settings.spm] artifactbundle_only = true` plus one tool entry with `artifactbundle = false` to opt that tool into source builds. The conflict check runs before any install attempt.","commonSituations":"Trying to exempt a single misbehaving package from a team-wide bundles-only policy.","solutions":["Remove `artifactbundle = false` from the tool entry (policy wins; the tool gets bundles or fails)","Turn off the global `spm.artifactbundle_only` setting and enforce bundles per-tool with `artifactbundle = true`","If you need per-tool escape hatches, model them as per-tool `artifactbundle = true` entries under a default-on policy that is not global"],"exampleFix":"# before\n[settings.spm]\nartifactbundle_only = true\n\n[tools.\"spm:foo/bar\"]\nversion = \"1.0.0\"\nartifactbundle = false\n\n# after\n[settings.spm]\nartifactbundle_only = true\n\n[tools.\"spm:foo/bar\"]\nversion = \"1.0.0\"","handlingStrategy":"validation","validationCode":"mise settings get spm.artifactbundle_only | grep -q true && grep -Rn 'artifactbundle[[:space:]]*=[[:space:]]*false' mise.toml *.toml 2>/dev/null && echo 'conflict with artifactbundle_only'","typeGuard":"fn no_source_only_under_policy(tool: &toml::Value, policy_on: bool) -> bool {\n    !(policy_on && tool.get(\"artifactbundle\").and_then(|v| v.as_str()) == Some(\"false\"))\n}","tryCatchPattern":null,"preventionTips":["Don't mix global bundles-only policy with per-tool artifactbundle = false opt-outs","Change the policy itself instead of contradicting it per tool"],"tags":["spm","swift","conflicting-options","settings","mise-toml"],"backgroundTag":"conflicting-config-options","analyzedSha":"6f52dcdf99e282ef7a7db68c81301fa4618d0f79","analyzedAt":"2026-08-22T10:14:23.840Z","schemaVersion":2},"datasetVersion":"2026-08-30T08:17:16.595Z"}