astrid-runtime/astrid · error
signed channel release tag does not match its version
Error message
signed channel release tag does not match its version
What it means
The pointer's release tag must be exactly `v` followed by the canonical version string (format!("v{version}")). A mismatch means the tag, version, or both were edited independently, breaking the binding between the git tag the artifacts were built from and the version advertised in the channel.
Solutions
- Set `release.tag` to `v` + the exact canonical version string (e.g. version `1.2.3` → tag `v1.2.3`) and republish
- Regenerate the pointer with the release workflow instead of editing TOML by hand
- Verify the git tag actually pushed matches `v{version}` and update the pointer to that tag
- Check for invisible whitespace/case differences in the tag field
Example fix
// before (channel.toml) version = "1.2.3" tag = "1.2.3" // after version = "1.2.3" tag = "v1.2.3"
Defensive patterns
Strategy: validation
Validate before calling
fn tag_matches_version(tag: &str, version: &str) -> bool {
tag == format!("v{version}")
} Type guard
fn has_matching_tag(release: &ReleaseRef) -> bool {
release.tag == format!("v{}", release.version)
} Try / catch
match parse_channel(&bytes, channel, now) {
Err(e) if e.to_string().contains("tag does not match") => {
anyhow::bail!("channel metadata tag/version mismatch; regenerate pointer from the release tag")
}
other => other?,
} Prevention
- Format the tag as format!("v{version}") in the publisher rather than typing it
- Never edit tag and version independently in signed metadata
- Keep the git tag push and channel pointer generation in the same workflow step
When it happens
Trigger: parse_channel or enforce_continuity reads a pointer where `release.tag != "v" + canonical_version(release.version)` — e.g. tag `release-1.2.3`, tag missing the `v` prefix (`1.2.3`), or version/tag edited separately.
Common situations: Hand-written channel TOML where tag was typed manually; release tooling that strips the `v` prefix; version bumped in one field but not the other during a hotfix.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- must contain exactly targets
- nightly channel must point to an exact nightly prerelease
- signed channel generation must be positive
- signed channel lifetime exceeds the maximum for its channel
- signed channel lifetime is invalid
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/6483863bd1d2518d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-cli/src/commands/update_channel.rs:513
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"
);
}
ensure!(
pointer.release.metadata_asset == format!("astrid-{version}-release.toml"),
"signed channel release metadata asset is invalid"
);
ensure!(View on GitHub (pinned to affd8760f4)