astrid-runtime/astrid · error

principal migration component has no ordinary-home receipt:

Error message

principal migration component has no ordinary-home receipt: {}

What it means

`validate_existing_proofs` skips mutable components, then requires that any immutable component whose name encodes a principal UID has a corresponding ordinary-home receipt (i.e. its UID is present in principal_homes). If a principal component exists in the ledger but its UID has no ordinary-home receipt, validation fails. This ensures principals recorded in the migration ledger were also proven at the ordinary-home level.

Source

Thrown at crates/astrid-kernel/src/legacy_migration_barrier/ledger.rs:405

) -> io::Result<()> {
    // The ledger is historical: mutable profile/package summaries and deleted
    // principal UIDs are not required to be present on a later boot.
    let mut principal_homes = std::collections::BTreeSet::new();
    for component in &existing.components {
        if let Some(uid) = principal_component_uid(&component.name)
            && component.name.ends_with(":home")
        {
            principal_homes.insert(uid);
        }
    }
    for component in &existing.components {
        if mutable_component(&component.name) {
            continue;
        }
        if let Some(uid) = principal_component_uid(&component.name)
            && !principal_homes.contains(&uid)
        {
            return Err(io::Error::new(
                io::ErrorKind::InvalidData,
                format!(
                    "principal migration component has no ordinary-home receipt: {}",
                    component.name
                ),
            ));
        }
        if let Some(current) = proofs.get(&component.name) {
            if current != &component.destination_proof {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    format!(
                        "destination receipt changed for migration component {}",
                        component.name
                    ),
                ));
            }
            continue;

View on GitHub (pinned to affd8760f4)

Solutions

  1. Regenerate or restore the missing ordinary-home receipt for that UID (re-run migration so collect_destination_proofs recreates it).
  2. If the UID is legitimately gone (deleted historical user), re-run resume_existing_layout so the ledger is revalidated under the current rules — deleted historical UIDs are handled by the live-projection check, not this one.
  3. Do not hand-edit the ledger; bring ledger and receipts back into consistency by re-migrating.

Example fix

// before: ledger has system:principal-1000 but no principal-home-1000.json
$ rm ledger && astrid migrate  # regenerate receipts + ledger together
Defensive patterns

Strategy: validation

Validate before calling

let uid = principal_component_uid(&component.name);
let ok = uid.map(|u| principal_homes.contains(&u)).unwrap_or(true);
if !ok { eprintln!("{} has no ordinary-home receipt", component.name); }

Try / catch

match resume_existing_layout(...) {
    Err(e) if e.to_string().contains("no ordinary-home receipt") => {
        eprintln!("regenerate receipts via a fresh migration run");
    }
    r => r?,
}

Prevention

When it happens

Trigger: validate_existing_proofs (via resume_existing_layout or existing_layout_requires_receipts_for_live_immutable_components) encounters an immutable principal component whose parsed UID is absent from the set of validated principal_homes receipts.

Common situations: The ordinary-home receipt was deleted or never written while the principal component entry survived in the ledger; a partial restore restored the ledger but not the receipts; UID changed/removed (userdel) between migrations.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


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