astrid-runtime/astrid · error

keypair was written by a newer astrid (schema > )

Error message

keypair {} was written by a newer astrid (schema {} > {})

What it means

`read_meta` parses a keypair's TOML metadata and refuses to proceed if the file's schema_version is greater than the schema version this astrid build supports. This prevents misinterpreting metadata written by a newer client.

Solutions

  1. Upgrade astrid to a version whose META_SCHEMA_VERSION is >= the file's schema version.
  2. Copy the keypair metadata back to a machine running the newer astrid that wrote it.
  3. As a last resort, back up and hand-edit/downgrade the meta file — risky, only if fields are understood.
  4. Avoid downgrading the CLI on machines sharing key directories.

Example fix

// before
astrid 0.3 (schema 2) reading meta with schema_version = 3
// after
upgrade astrid to >= the version that wrote schema 3, then retry
Defensive patterns

Strategy: try-catch

Validate before calling

grep -q "schema_version = $MAX_SUPPORTED" "$KEYDIR/$NAME.meta" || echo "meta schema too new" >&2

Try / catch

match read_meta(&paths) { Err(e) if e.to_string().contains("newer astrid") => upgrade_astrid()?, m => m?, }

Prevention

When it happens

Trigger: Reading (show, pubkey, invite redeem via --keypair, binding record/scan) a keypair whose meta file was written by a newer astrid release with a bumped META_SCHEMA_VERSION.

Common situations: Switching between machines with different astrid versions; downgrading the CLI; shared/network key directory written by a newer install; CI image with an older astrid.

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/d192b6088eb4e91b. Report an issue: GitHub.

Appendix: source

Thrown at crates/astrid-cli/src/commands/keypair.rs:475

    Ok(())
}

fn read_public(path: &Path) -> Result<String> {
    let raw = fs::read_to_string(path).with_context(|| format!("read {}", path.display()))?;
    let trimmed = raw.trim().to_string();
    if trimmed.len() != 64 || !trimmed.chars().all(|c| c.is_ascii_hexdigit()) {
        bail!("{} is not a 64-char hex public key", path.display());
    }
    Ok(trimmed)
}

fn read_meta(paths: &KeyPaths) -> Result<KeyMeta> {
    let text = fs::read_to_string(&paths.meta)
        .with_context(|| format!("read {}", paths.meta.display()))?;
    let meta: KeyMeta =
        toml::from_str(&text).with_context(|| format!("parse {}", paths.meta.display()))?;
    if meta.schema_version > META_SCHEMA_VERSION {
        bail!(
            "keypair {} was written by a newer astrid (schema {} > {})",
            paths.meta.display(),
            meta.schema_version,
            META_SCHEMA_VERSION
        );
    }
    if meta.schema_version < META_SCHEMA_VERSION {
        let public_hex = match read_public(&paths.public_hex) {
            Ok(public_hex) => public_hex,
            Err(error) => {
                tracing::warn!(
                    path = %paths.meta.display(),
                    %error,
                    "keypair fingerprint migration deferred until a valid public key is available"
                );
                return Ok(meta);
            },
        };

View on GitHub (pinned to affd8760f4)