{"record":{"id":"b1b56b7f462fc4d9","repo":"astrid-runtime/astrid","slug":"signed-channel-identity-is-invalid","errorCode":null,"errorMessage":"signed channel identity is invalid","messagePattern":"signed channel identity is invalid","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/update_channel.rs","lineNumber":462,"sourceCode":"\npub(super) fn parse_channel(\n    bytes: &[u8],\n    expected_channel: UpdateChannel,\n    now: DateTime<Utc>,\n) -> anyhow::Result<ChannelPointer> {\n    let text = std::str::from_utf8(bytes).context(\"signed channel metadata is not UTF-8\")?;\n    let pointer: ChannelPointer =\n        toml::from_str(text).context(\"signed channel metadata is invalid TOML\")?;\n    validate_pointer(&pointer, expected_channel, Some(now))?;\n    Ok(pointer)\n}\n\nfn validate_pointer(\n    pointer: &ChannelPointer,\n    expected_channel: UpdateChannel,\n    now: Option<DateTime<Utc>>,\n) -> anyhow::Result<()> {\n    ensure!(\n        pointer.schema_version == 1\n            && pointer.kind == \"astrid-channel\"\n            && pointer.product == PRODUCT\n            && pointer.repository == REPOSITORY,\n        \"signed channel identity is invalid\"\n    );\n    ensure!(\n        pointer.channel == expected_channel.as_str(),\n        \"signed channel names '{}', expected '{}'\",\n        pointer.channel,\n        expected_channel.as_str()\n    );\n    ensure!(\n        pointer.generation > 0,\n        \"signed channel generation must be positive\"\n    );\n    let published = canonical_time(&pointer.published_at, \"published-at\")?;\n    let expires = canonical_time(&pointer.expires_at, \"expires-at\")?;","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/update_channel.rs#L444-L480","documentation":"The channel pointer's identity fields failed validation: schema_version must be 1, kind must be \"astrid-channel\", and product/repository must match the built-in PRODUCT and REPOSITORY constants. This guard ensures the signed pointer belongs to this product and repo, failing closed on anything else.","triggerScenarios":"parse_channel or enforce_continuity encounters a pointer whose schema_version != 1, kind is not \"astrid-channel\", product/repository differ from the compiled-in constants — e.g. a pointer from a fork, an older/newer schema, or a corrupted/hand-edited pointer file.","commonSituations":"Pointing the CLI at a channel file copied from another product or fork; a schema bump by the publisher not yet supported by the installed CLI; manual edits to the pointer JSON.","solutions":["Verify the channel pointer file points at the correct product and repository","Regenerate or re-download the pointer from the official source","Update the CLI to a version matching the pointer's schema_version","Restore the pointer file from a backup instead of editing it"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"fn pointer_identity_ok(p: &ChannelPointer, product: &str, repo: &str) -> bool {\n    p.schema_version == 1 && p.kind == \"astrid-channel\" && p.product == product && p.repository == repo\n}","typeGuard":"fn is_valid_pointer(p: &ChannelPointer) -> bool {\n    p.schema_version == 1 && p.kind == \"astrid-channel\"\n}","tryCatchPattern":"if !pointer_identity_ok(&pointer, PRODUCT, REPOSITORY) {\n    eprintln!(\"pointer is not for this product/repo; re-download it\");\n}","preventionTips":["Only obtain pointer files from the official repository","Don't share pointer files across forks/products","Keep the CLI in sync with the publisher's schema_version"],"tags":["identity-validation","channel-pointer","security"],"backgroundTag":"schema-validation-failed","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"}