{"record":{"id":"6483863bd1d2518d","repo":"astrid-runtime/astrid","slug":"signed-channel-release-tag-does-not-match-its-vers","errorCode":null,"errorMessage":"signed channel release tag does not match its version","messagePattern":"signed channel release tag does not match its version","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/update_channel.rs","lineNumber":513,"sourceCode":"        UpdateChannel::Nightly => chrono::Duration::days(2),\n    };\n    ensure!(\n        expires.signed_duration_since(published) <= max_lifetime,\n        \"signed channel lifetime exceeds the maximum for its channel\"\n    );\n    let version = canonical_version(&pointer.release.version)?;\n    let nightly_commit = nightly_source_commit(&version);\n    match expected_channel {\n        UpdateChannel::Nightly => ensure!(\n            nightly_commit.is_some() && version.build.is_empty(),\n            \"nightly channel must point to an exact nightly prerelease\"\n        ),\n        UpdateChannel::Stable | UpdateChannel::Dev => ensure!(\n            version.pre.is_empty() && version.build.is_empty(),\n            \"stable and dev channels must point to canonical releases\"\n        ),\n    }\n    ensure!(\n        pointer.release.tag == format!(\"v{version}\"),\n        \"signed channel release tag does not match its version\"\n    );\n    ensure!(\n        is_commit(&pointer.release.source_commit),\n        \"signed channel source commit is invalid\"\n    );\n    if let Some(commit) = nightly_commit {\n        ensure!(\n            commit == pointer.release.source_commit,\n            \"nightly channel version does not embed its source commit\"\n        );\n    }\n    ensure!(\n        pointer.release.metadata_asset == format!(\"astrid-{version}-release.toml\"),\n        \"signed channel release metadata asset is invalid\"\n    );\n    ensure!(","sourceCodeStart":495,"sourceCodeEnd":531,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/update_channel.rs#L495-L531","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before (channel.toml)\nversion = \"1.2.3\"\ntag = \"1.2.3\"\n// after\nversion = \"1.2.3\"\ntag = \"v1.2.3\"","handlingStrategy":"validation","validationCode":"fn tag_matches_version(tag: &str, version: &str) -> bool {\n    tag == format!(\"v{version}\")\n}","typeGuard":"fn has_matching_tag(release: &ReleaseRef) -> bool {\n    release.tag == format!(\"v{}\", release.version)\n}","tryCatchPattern":"match parse_channel(&bytes, channel, now) {\n    Err(e) if e.to_string().contains(\"tag does not match\") => {\n        anyhow::bail!(\"channel metadata tag/version mismatch; regenerate pointer from the release tag\")\n    }\n    other => other?,\n}","preventionTips":["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"],"tags":["update-channel","validation","release-tag"],"backgroundTag":"invalid-identifier-format","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}