{"record":{"id":"d192b6088eb4e91b","repo":"astrid-runtime/astrid","slug":"keypair-was-written-by-a-newer-astrid-schema","errorCode":null,"errorMessage":"keypair {} was written by a newer astrid (schema {} > {})","messagePattern":"keypair (.+?) was written by a newer astrid \\(schema (.+?) > (.+?)\\)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/keypair.rs","lineNumber":475,"sourceCode":"    Ok(())\n}\n\nfn read_public(path: &Path) -> Result<String> {\n    let raw = fs::read_to_string(path).with_context(|| format!(\"read {}\", path.display()))?;\n    let trimmed = raw.trim().to_string();\n    if trimmed.len() != 64 || !trimmed.chars().all(|c| c.is_ascii_hexdigit()) {\n        bail!(\"{} is not a 64-char hex public key\", path.display());\n    }\n    Ok(trimmed)\n}\n\nfn read_meta(paths: &KeyPaths) -> Result<KeyMeta> {\n    let text = fs::read_to_string(&paths.meta)\n        .with_context(|| format!(\"read {}\", paths.meta.display()))?;\n    let meta: KeyMeta =\n        toml::from_str(&text).with_context(|| format!(\"parse {}\", paths.meta.display()))?;\n    if meta.schema_version > META_SCHEMA_VERSION {\n        bail!(\n            \"keypair {} was written by a newer astrid (schema {} > {})\",\n            paths.meta.display(),\n            meta.schema_version,\n            META_SCHEMA_VERSION\n        );\n    }\n    if meta.schema_version < META_SCHEMA_VERSION {\n        let public_hex = match read_public(&paths.public_hex) {\n            Ok(public_hex) => public_hex,\n            Err(error) => {\n                tracing::warn!(\n                    path = %paths.meta.display(),\n                    %error,\n                    \"keypair fingerprint migration deferred until a valid public key is available\"\n                );\n                return Ok(meta);\n            },\n        };","sourceCodeStart":457,"sourceCodeEnd":493,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/keypair.rs#L457-L493","documentation":"`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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Upgrade astrid to a version whose META_SCHEMA_VERSION is >= the file's schema version.","Copy the keypair metadata back to a machine running the newer astrid that wrote it.","As a last resort, back up and hand-edit/downgrade the meta file — risky, only if fields are understood.","Avoid downgrading the CLI on machines sharing key directories."],"exampleFix":"// before\nastrid 0.3 (schema 2) reading meta with schema_version = 3\n// after\nupgrade astrid to >= the version that wrote schema 3, then retry","handlingStrategy":"try-catch","validationCode":"grep -q \"schema_version = $MAX_SUPPORTED\" \"$KEYDIR/$NAME.meta\" || echo \"meta schema too new\" >&2","typeGuard":null,"tryCatchPattern":"match read_meta(&paths) { Err(e) if e.to_string().contains(\"newer astrid\") => upgrade_astrid()?, m => m?, }","preventionTips":["Upgrade all machines sharing a key directory together","Never downgrade astrid below the version that wrote the keys","Record the astrid version alongside key material in backups"],"tags":["keypair","version-skew","schema"],"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"}