astrid-runtime/astrid · error
stable and dev channels must point to canonical releases
Error message
stable and dev channels must point to canonical releases
What it means
Stable and dev channel pointers must reference canonical releases: the version must have an empty pre-release segment and empty build metadata. A pointer on these channels to something like `1.2.3-rc.1` or `1.2.3+build5` is rejected because stable/dev distributions must come from final, unadorned versions.
Source
Thrown at crates/astrid-cli/src/commands/update_channel.rs:508
);
}
let max_lifetime = match expected_channel {
UpdateChannel::Stable => chrono::Duration::days(30),
UpdateChannel::Dev => chrono::Duration::days(7),
UpdateChannel::Nightly => chrono::Duration::days(2),
};
ensure!(
expires.signed_duration_since(published) <= max_lifetime,
"signed channel lifetime exceeds the maximum for its channel"
);
let version = canonical_version(&pointer.release.version)?;
let nightly_commit = nightly_source_commit(&version);
match expected_channel {
UpdateChannel::Nightly => ensure!(
nightly_commit.is_some() && version.build.is_empty(),
"nightly channel must point to an exact nightly prerelease"
),
UpdateChannel::Stable | UpdateChannel::Dev => ensure!(
version.pre.is_empty() && version.build.is_empty(),
"stable and dev channels must point to canonical releases"
),
}
ensure!(
pointer.release.tag == format!("v{version}"),
"signed channel release tag does not match its version"
);
ensure!(
is_commit(&pointer.release.source_commit),
"signed channel source commit is invalid"
);
if let Some(commit) = nightly_commit {
ensure!(
commit == pointer.release.source_commit,
"nightly channel version does not embed its source commit"
);
}View on GitHub (pinned to affd8760f4)
Solutions
- Point the stable/dev channel at the final release version (e.g. `1.2.3`, no suffix) and republish
- Publish pre-releases under the nightly channel, or don't publish them as channel pointers at all
- Strip build metadata when promoting a tested build to stable, then cut a proper release tag
- Re-run the release workflow for the correct channel
Example fix
// before (dev channel.toml) version = "1.2.3-rc.1" // after version = "1.2.3"
Defensive patterns
Strategy: validation
Validate before calling
fn stable_or_dev_version_ok(v: &semver::Version) -> bool {
v.pre.is_empty() && v.build.is_empty()
} Type guard
fn is_canonical_release(version: &str) -> bool {
semver::Version::parse(version)
.map(|v| v.pre.is_empty() && v.build.is_empty())
.unwrap_or(false)
} Try / catch
match parse_channel(&bytes, UpdateChannel::Stable, now) {
Err(e) if e.to_string().contains("canonical releases") => {
anyhow::bail!("stable channel must not point at a prerelease; publish the final version")
}
other => other?,
} Prevention
- Only promote fully released (no pre/build suffix) versions to stable/dev
- Publish RCs and nightlies solely under the nightly channel
- Add a pre-publish lint asserting version.pre.is_empty() && version.build.is_empty() for these channels
When it happens
Trigger: parse_channel or enforce_continuity with expected_channel = Stable or Dev and a version containing `version.pre` (e.g. `2.0.0-rc.1`, `0.5.0-nightly.20260909.deadbeef`) or non-empty `version.build`.
Common situations: Copying a nightly pointer into the dev channel during testing; publishing an RC to the stable channel; a release script forgetting to strip build metadata after the final tag.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- signed channel version '{value}' is not canonical semver
- nightly channel must point to an exact nightly prerelease
- opaque capsule asset directories cannot be symlinks: {}
- distro.version '{}' is not valid semver
- distro.astrid-version '{av}' is not a valid semver requireme
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/bc2001a3d109c31e.
Report an issue: GitHub.