astrid-runtime/astrid · error
distro.requires.{ns}.{name} '{req}' is not a valid semver re
Error message
distro.requires.{ns}.{name} '{req}' is not a valid semver requirement What it means
validate_manifest iterates `manifest.distro.requires` (namespace -> interface -> requirement) and bails if any requirement string fails `semver::VersionReq::parse`. These requirements declare which interface versions a distro consumes, so each must be a valid semver requirement. The namespace and interface names are included in the message to pinpoint the offending entry.
Source
Thrown at crates/astrid-cli/src/commands/distro/validate.rs:113
if semver::Version::parse(&manifest.distro.version).is_err() {
anyhow::bail!(
"distro.version '{}' is not valid semver",
manifest.distro.version,
);
}
// astrid-version is valid semver requirement (if set).
if let Some(ref av) = manifest.distro.astrid_version
&& semver::VersionReq::parse(av).is_err()
{
anyhow::bail!("distro.astrid-version '{av}' is not a valid semver requirement");
}
// Requires version strings are valid semver requirements.
for (ns, ifaces) in &manifest.distro.requires {
for (name, req) in ifaces {
if semver::VersionReq::parse(req).is_err() {
anyhow::bail!(
"distro.requires.{ns}.{name} '{req}' is not a valid semver requirement",
);
}
}
}
// At least one capsule.
if manifest.capsules.is_empty() {
anyhow::bail!("distro must contain at least one capsule");
}
// No duplicate capsule names, and each name must be a valid
// identifier. Names become path components in the `.shuttle` layout
// (`capsules/<name>.capsule`) and on disk under the capsule store;
// constraining them to `^[a-z][a-z0-9-]*$` keeps a manifest from
// introducing `/`, `..`, or other path-hostile characters there.
let mut seen_names = HashSet::new();
for cap in &manifest.capsules {View on GitHub (pinned to affd8760f4)
Solutions
- Locate the `distro.requires.{ns}.{name}` entry named in the error and rewrite its value as a valid semver requirement (e.g. `^1.0`, `>=0.3, <0.5`).
- Remove the entry if the requirement is unnecessary.
- Check each requirement with a semver parser/regex before re-running validation.
Example fix
# before [distro.requires.core] http = "v2" # after [distro.requires.core] http = "^2.0"
Defensive patterns
Strategy: validation
Validate before calling
for (ns, ifaces) in &manifest.distro.requires {
for (name, req) in ifaces {
if semver::VersionReq::parse(req).is_err() {
eprintln!("bad requirement {ns}.{name} = '{req}'");
}
}
} Type guard
fn is_semver_req(s: &str) -> bool {
semver::VersionReq::parse(s).is_ok()
} Try / catch
if let Err(e) = validate_manifest(&manifest) {
if e.to_string().contains("not a valid semver requirement") {
// surface the offending ns.name from the message and correct the TOML
}
} Prevention
- Use only semver operators supported by the semver crate (^, ~, =, >, <, >=, <=, *)
- Never paste git tags or commit hashes into requires entries
- Add a manifest linter to CI that parses every requirement
When it happens
Trigger: A distro manifest with a `[distro.requires.<ns>]` entry whose version string is not a valid semver requirement — e.g. `api = "1.0"` (missing operator is actually valid; invalid ones are `"v2"`, `"*.*"`, `"~1.2.3.4"`, `">= 1.x"` typos, embedded whitespace).
Common situations: Typos when declaring interface requirements; pasting a git tag or commit-ish string; using Maven/npm-only version syntax not supported by the semver crate.
Understand the failure class
Background: "Invalid value" and "allowed values are" config errors: what your library rejected and how to fix it — this error's family across 41 libraries.
Related errors
- distro.astrid-version '{av}' is not a valid semver requireme
- capsule '{}': version '{}' is not valid semver
- distro.version '{}' is not valid semver
- distro must contain at least one capsule
- capsule name '{}' is invalid (must match ^[a-z][a-z0-9-]*$)
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/c5254ad37672b3ac.
Report an issue: GitHub.