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

  1. Set `release.tag` to `v` + the exact canonical version string (e.g. version `1.2.3` → tag `v1.2.3`) and republish
  2. Regenerate the pointer with the release workflow instead of editing TOML by hand
  3. Verify the git tag actually pushed matches `v{version}` and update the pointer to that tag
  4. 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

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


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)