astrid-runtime/astrid · error

{label} release metadata identity is invalid

Error message

{label} release metadata identity is invalid

What it means

This error is thrown by verify_release_extension when the parsed release-extension TOML metadata has an identity that does not match what the updater requires: schema_version must be 1, kind must equal the expected extension kind ("musl" or "Windows"), and product/repository must equal the built-in PRODUCT and REPOSITORY constants. It is a supply-chain integrity check that ensures the downloaded metadata file actually describes this product's release format before any hash or version data from it is trusted.

Source

Thrown at crates/astrid-cli/src/commands/update_channel.rs:656

#[allow(clippy::too_many_arguments)]
fn verify_release_extension(
    bytes: &[u8],
    legacy_manifest_bytes: &[u8],
    pointer: &ChannelPointer,
    target: &str,
    expected_kind: &str,
    expected_targets: &[&str],
    label: &str,
) -> anyhow::Result<String> {
    ensure!(
        expected_targets.contains(&target),
        "{label} release metadata does not support target '{target}'"
    );
    let text = std::str::from_utf8(bytes)
        .with_context(|| format!("{label} release metadata is not UTF-8"))?;
    let extension: ReleaseExtension = toml::from_str(text)
        .with_context(|| format!("{label} release metadata is invalid TOML"))?;
    ensure!(
        extension.schema_version == 1
            && extension.kind == expected_kind
            && extension.product == PRODUCT
            && extension.repository == REPOSITORY,
        "{label} release metadata identity is invalid"
    );
    canonical_version(&extension.version)?;
    ensure!(
        extension.version == pointer.release.version
            && extension.tag == pointer.release.tag
            && extension.source_commit == pointer.release.source_commit
            && extension.release_workflow_identity == pointer.release.release_workflow_identity,
        "{label} release metadata does not match the authenticated legacy release"
    );
    ensure!(
        extension.legacy_release.metadata_asset == pointer.release.metadata_asset
            && extension.legacy_release.metadata_blake3 == pointer.release.metadata_blake3
            && blake3::hash(legacy_manifest_bytes).to_hex().as_str()

View on GitHub (pinned to affd8760f4)

Solutions

  1. Regenerate the release extension metadata with the current release tooling so schema_version=1 and kind/product/repository match the constants in update_channel.rs
  2. Verify the downloaded metadata asset comes from the authenticated release for PRODUCT/REPOSITORY and was not substituted by a mirror or proxy cache
  3. Check you are passing the right metadata file to the right verifier (musl metadata to verify_musl_extension, Windows metadata to verify_windows_extension)
  4. If you fork the product, update the PRODUCT/REPOSITORY constants or the publishing pipeline to emit matching identity fields

Example fix

// before: channel config pointing at a fork's extension metadata
channel = "https://mirror.example.com/fork/astrid-release-musl-extension.toml"
// after: use the official product's extension metadata
channel = "https://releases.astrid.dev/stable/astrid-release-musl-extension.toml"
Defensive patterns

Strategy: validation

Validate before calling

fn metadata_identity_ok(text: &str, product: &str, repository: &str, kind: &str) -> bool {
    match text.parse::<toml::Table>() {
        Ok(t) => t.get("schema_version").and_then(|v| v.as_integer()) == Some(1)
            && t.get("kind").and_then(|v| v.as_str()) == Some(kind)
            && t.get("product").and_then(|v| v.as_str()) == Some(product)
            && t.get("repository").and_then(|v| v.as_str()) == Some(repository),
        Err(_) => false,
    }
}

Type guard

fn is_valid_extension(e: &ReleaseExtension, expected_kind: &str) -> bool {
    e.schema_version == 1 && e.kind == expected_kind
}

Try / catch

match verify_musl_extension(&bytes, &manifest, &pointer, target) {
    Ok(blake3) => proceed(blake3),
    Err(e) if e.to_string().contains("identity is invalid") => {
        eprintln!("metadata does not belong to this product/schema; refusing update");
        abort_update();
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling resolve_target_blake3, verify_musl_extension, or verify_windows_extension with bytes of a metadata file whose TOML parses but has schema_version != 1, a kind field not matching the expected extension kind, or product/repository fields differing from PRODUCT/REPOSITORY (e.g. a metadata file for a different repo or an older schema).

Common situations: Pointing the update channel at a third-party fork whose release extensions declare a different repository; serving stale extension metadata generated by an older schema_version; accidentally substituting a musl metadata file where the Windows extension is verified (kind mismatch); hand-edited release metadata.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09). Data as JSON: /api/errors/d1aeac78945e11e1. Report an issue: GitHub.