{"record":{"id":"7d19ee351a9bc253","repo":"astrid-runtime/astrid","slug":"capsule-branch-rev-require-building-from-sou","errorCode":null,"errorMessage":"capsule '{}': branch/rev require building from source and are not allowed in a distro manifest — pin a released `version` or `tag` (git-ref installs are available via `astrid capsule install`).","messagePattern":"capsule '(.+?)': branch/rev require building from source and are not allowed in a distro manifest — pin a released `version` or `tag` \\(git-ref installs are available via `astrid capsule install`\\)\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/distro/validate.rs","lineNumber":148,"sourceCode":"    let mut seen_names = HashSet::new();\n    for cap in &manifest.capsules {\n        if !is_valid_id(&cap.name) {\n            anyhow::bail!(\n                \"capsule name '{}' is invalid (must match ^[a-z][a-z0-9-]*$)\",\n                cap.name,\n            );\n        }\n        if !seen_names.insert(&cap.name) {\n            anyhow::bail!(\"duplicate capsule name '{}'\", cap.name);\n        }\n        // Distros compose *released* capsules. `branch`/`rev` selectors\n        // can only be honored by compiling from a git ref — the exact\n        // toolchain dependency offline/headless distro seeding exists to\n        // remove. Reject them: a distro must pin a released `version` or\n        // `tag`. (Git-ref installs remain available via the standalone\n        // `astrid capsule install` command.)\n        if cap.branch.is_some() || cap.rev.is_some() {\n            anyhow::bail!(\n                \"capsule '{}': branch/rev require building from source and are not allowed in a \\\n                 distro manifest — pin a released `version` or `tag` (git-ref installs are \\\n                 available via `astrid capsule install`).\",\n                cap.name,\n            );\n        }\n        let version = cap.version.trim();\n        if cap.version != version {\n            anyhow::bail!(\n                \"capsule '{}': version must not contain surrounding whitespace\",\n                cap.name\n            );\n        }\n        if !version.is_empty() && Version::parse(version).is_err() {\n            anyhow::bail!(\n                \"capsule '{}': version '{}' is not valid semver\",\n                cap.name,\n                cap.version","sourceCodeStart":130,"sourceCodeEnd":166,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/distro/validate.rs#L130-L166","documentation":"Distros compose *released* capsules so they can be seeded offline/headless without a toolchain. `branch` and `rev` selectors would require compiling from a git ref, defeating that purpose, so validate_manifest rejects any capsule specifying either. Git-ref installs remain available via the standalone `astrid capsule install` command.","triggerScenarios":"A `[[capsules]]` entry in a distro manifest with `branch = \"main\"` and/or `rev = \"abc123\"` set (either one triggers the bail).","commonSituations":"Copying a capsule-install invocation's git-ref fields into a distro manifest; wanting an unreleased fix in a distro; migrating a dev manifest into a distro manifest without pinning a release.","solutions":["Replace `branch`/`rev` with a released `version` (exact semver) or `tag` field.","Publish/release the capsule version you need, then pin that version in the distro.","If you genuinely need a git-ref build, install it via `astrid capsule install` outside the distro manifest."],"exampleFix":"# before\n[[capsules]]\nname = \"http\"\nbranch = \"main\"\n\n# after\n[[capsules]]\nname = \"http\"\nversion = \"1.4.2\"","handlingStrategy":"validation","validationCode":"for cap in &manifest.capsules {\n    if cap.branch.is_some() || cap.rev.is_some() {\n        panic!(\"capsule '{}' uses branch/rev; pin a version or tag\", cap.name);\n    }\n}","typeGuard":null,"tryCatchPattern":"if let Err(e) = validate_manifest(&manifest) {\n    if e.to_string().contains(\"branch/rev require building from source\") {\n        eprintln!(\"pin a release instead: {e}\");\n    }\n}","preventionTips":["Reserve branch/rev selectors for `astrid capsule install`, never distro manifests","Always pin distro capsules to a released version or tag","Release the needed capsule version before adding it to a distro"],"tags":["cli","manifest","unsupported-operation","validation"],"backgroundTag":"unsupported-config-value","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}