astrid-runtime/astrid · error
capsule '{}': branch/rev require building from source and ar
Error message
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`). What it means
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.
Source
Thrown at crates/astrid-cli/src/commands/distro/validate.rs:148
let mut seen_names = HashSet::new();
for cap in &manifest.capsules {
if !is_valid_id(&cap.name) {
anyhow::bail!(
"capsule name '{}' is invalid (must match ^[a-z][a-z0-9-]*$)",
cap.name,
);
}
if !seen_names.insert(&cap.name) {
anyhow::bail!("duplicate capsule name '{}'", cap.name);
}
// Distros compose *released* capsules. `branch`/`rev` selectors
// can only be honored by compiling from a git ref — the exact
// toolchain dependency offline/headless distro seeding exists to
// remove. Reject them: a distro must pin a released `version` or
// `tag`. (Git-ref installs remain available via the standalone
// `astrid capsule install` command.)
if cap.branch.is_some() || cap.rev.is_some() {
anyhow::bail!(
"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`).",
cap.name,
);
}
let version = cap.version.trim();
if cap.version != version {
anyhow::bail!(
"capsule '{}': version must not contain surrounding whitespace",
cap.name
);
}
if !version.is_empty() && Version::parse(version).is_err() {
anyhow::bail!(
"capsule '{}': version '{}' is not valid semver",
cap.name,
cap.versionView on GitHub (pinned to affd8760f4)
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.
Example fix
# before [[capsules]] name = "http" branch = "main" # after [[capsules]] name = "http" version = "1.4.2"
Defensive patterns
Strategy: validation
Validate before calling
for cap in &manifest.capsules {
if cap.branch.is_some() || cap.rev.is_some() {
panic!("capsule '{}' uses branch/rev; pin a version or tag", cap.name);
}
} Try / catch
if let Err(e) = validate_manifest(&manifest) {
if e.to_string().contains("branch/rev require building from source") {
eprintln!("pin a release instead: {e}");
}
} Prevention
- 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
When it happens
Trigger: A `[[capsules]]` entry in a distro manifest with `branch = "main"` and/or `rev = "abc123"` set (either one triggers the bail).
Common situations: 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.
Related errors
- distro.astrid-version '{av}' is not a valid semver requireme
- distro.requires.{ns}.{name} '{req}' is not a valid semver re
- distro must contain at least one capsule
- capsule name '{}' is invalid (must match ^[a-z][a-z0-9-]*$)
- duplicate capsule name '{}'
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/7d19ee351a9bc253.
Report an issue: GitHub.