astrid-runtime/astrid · error

legacy revocation file exceeds entry cap

Error message

legacy revocation file exceeds entry cap

What it means

Size guard in migrate_legacy_file: the legacy JSON revocation file exceeded the migration byte cap, so the one-time import is aborted instead of ingesting a suspiciously large file into the control KV.

Solutions

  1. Inspect the legacy JSON for corruption or duplicated entries and trim it
  2. Complete migration with a hand-curated, capped file and write the receipt manually
  3. Confirm the KV already holds the epochs, then delete the legacy file
Defensive patterns

Strategy: fallback

When it happens

Trigger: Thrown at crates/astrid-gateway/src/revocations.rs:380 when the library encounters an invalid state.

Common situations: See trigger scenarios.


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

Appendix: source

Thrown at crates/astrid-gateway/src/revocations.rs:380

    };
    if metadata.file_type().is_symlink() || !metadata.is_file() {
        anyhow::bail!(
            "legacy gateway revocation path is not a regular file: {}",
            path.display()
        );
    }
    if metadata.len() > MAX_REVOCATIONS_FILE_BYTES {
        anyhow::bail!("legacy revocation file exceeds migration cap");
    }
    let bytes = read_legacy_bytes(&path)?;
    let text = std::str::from_utf8(&bytes).context("legacy revocation file is not UTF-8")?;
    let raw: HashMap<String, u64> = if text.trim().is_empty() {
        HashMap::new()
    } else {
        serde_json::from_str(text).with_context(|| format!("parse {}", path.display()))?
    };
    if raw.len() > MAX_REVOCATION_ENTRIES {
        anyhow::bail!("legacy revocation file exceeds entry cap");
    }
    let digest = blake3::hash(&bytes).to_hex().to_string();
    let entries = raw
        .into_iter()
        .map(|(alias, epoch)| {
            PrincipalId::new(&alias)
                .map(|principal| (principal, epoch))
                .map_err(|error| anyhow::anyhow!("invalid principal {alias:?}: {error}"))
        })
        .collect::<anyhow::Result<Vec<_>>>()?;
    for (principal, epoch) in &entries {
        record_principal_max(store, principal, *epoch).await?;
    }
    let (principals, _) = load_from_store(store).await?;
    for (principal, epoch) in &entries {
        let durable = principals.get(principal).copied().ok_or_else(|| {
            anyhow::anyhow!("principal revocation {principal} missing after migration")
        })?;

View on GitHub (pinned to affd8760f4)