{"record":{"id":"4d6d526344a6b543","repo":"astrid-runtime/astrid","slug":"gateway-revocation-migration-receipt-conflicts","errorCode":null,"errorMessage":"gateway revocation migration receipt conflicts","messagePattern":"gateway revocation migration receipt conflicts","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-gateway/src/revocations.rs","lineNumber":417,"sourceCode":"        if durable < *epoch {\n            anyhow::bail!(\n                \"principal revocation {principal} read back epoch {durable}, expected at least {epoch}\"\n            );\n        }\n    }\n    let receipt = LegacyMigrationReceipt {\n        schema: 1,\n        digest,\n        principal_count: entries.len(),\n    };\n    let encoded = serde_json::to_vec(&receipt).context(\"encode revocation migration receipt\")?;\n    let existing = store\n        .get(REVOCATION_NAMESPACE, MIGRATION_RECEIPT_KEY)\n        .await\n        .map_err(|error| anyhow::anyhow!(\"read revocation migration receipt: {error}\"))?;\n    if let Some(existing) = existing {\n        if existing != encoded {\n            anyhow::bail!(\"gateway revocation migration receipt conflicts\");\n        }\n    } else if !store\n        .compare_and_swap(REVOCATION_NAMESPACE, MIGRATION_RECEIPT_KEY, None, encoded)\n        .await\n        .map_err(|error| anyhow::anyhow!(\"write revocation migration receipt: {error}\"))?\n    {\n        anyhow::bail!(\"gateway revocation migration receipt raced; retry startup\");\n    }\n    let _ = load_from_store(store).await?;\n    match std::fs::remove_file(&path) {\n        Ok(()) => {},\n        Err(error) if error.kind() == std::io::ErrorKind::NotFound => {},\n        Err(error) => return Err(anyhow::anyhow!(\"retire {}: {error}\", path.display())),\n    }\n    Ok(true)\n}\n\n/// Spawn the audit-event watcher. Subscribes to the kernel's audit","sourceCodeStart":399,"sourceCodeEnd":435,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-gateway/src/revocations.rs#L399-L435","documentation":"Receipt conflict in migrate_legacy_file: a migration receipt already exists in the control KV but its encoded bytes differ from the receipt computed for this legacy file — a different digest or count, meaning the file changed after a previous migration or two sources disagree.","triggerScenarios":"Thrown at crates/astrid-gateway/src/revocations.rs:417 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Compare the existing receipt's digest with the current file's blake3 digest","If the file was edited after migration, restore the original or re-derive entries manually","If the existing receipt is stale/incorrect, remove it deliberately and re-run migration"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"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"}