astrid-runtime/astrid · error · io::Error

InvalidData

InvalidData

Error message

legacy audit source for {alias} was inventoried but is missing: {}

What it means

The legacy audit rejection pass keeps an inventory of legacy audit sources per alias. If an alias was inventoried as a supported-but-handled source yet its path no longer exists on disk when reject_unsupported_sources runs, this InvalidData error is raised — the accounting and the filesystem disagree.

Source

Thrown at crates/astrid-kernel/src/legacy_migration_barrier/legacy_audit.rs:39

    home: &AstridHome,
    alias: &PrincipalId,
    source: Option<&SourceIdentity>,
) -> io::Result<()> {
    let Some(source) = source else {
        return Ok(());
    };
    if !source.present {
        return Ok(());
    }
    let path = home.principal_home(alias).audit_dir();
    if source.entries == SourceCount::ZERO {
        if path_exists(&path)? {
            retire_empty_directory(&path)?;
        }
        return Ok(());
    }
    if !path_exists(&path)? {
        return Err(io::Error::new(
            io::ErrorKind::InvalidData,
            format!(
                "legacy audit source for {alias} was inventoried but is missing: {}",
                path.display()
            ),
        ));
    }
    quarantine_audit_tree(home, alias, &path)
}

fn quarantine_audit_tree(home: &AstridHome, alias: &PrincipalId, source: &Path) -> io::Result<()> {
    let quarantine_root = home.migrations_dir().join(QUARANTINE_DIR);
    astrid_core::platform_fs::ensure_private_directory(&quarantine_root)?;
    let destination = unique_destination(&quarantine_root, alias.as_str())?;
    fs::rename(source, &destination).map_err(|error| {
        io::Error::new(
            error.kind(),
            format!(

View on GitHub (pinned to affd8760f4)

Solutions

  1. Restore the missing legacy audit directory for that alias, or
  2. Rebuild/clear the migration inventory so it no longer lists the missing source, then re-run
  3. Check whether another process deleted the audit tree and serialize cleanup with migration
  4. If the tree was already intentionally migrated, complete that alias's migration state so this pass skips it

Example fix

// before: inventory says alias has a legacy source, but dir was deleted
// after: re-inventory before rejecting unsupported sources
let sources = inventory_legacy_sources(&home)?;
reject_unsupported_sources(&home, &sources)?;
Defensive patterns

Strategy: validation

Validate before calling

if !path_exists(&audit_path_for(alias))? {
    // rebuild inventory or skip the alias before calling reject_unsupported_sources
}

Try / catch

if let Err(e) = reject_unsupported_sources(&home, &sources) {
    if e.to_string().contains("was inventoried but is missing") {
        let fresh = inventory_legacy_sources(&home)?;
        reject_unsupported_sources(&home, &fresh)?;
    }
}

Prevention

When it happens

Trigger: handle_non_default_audit_source (called by reject_unsupported_sources) checks path_exists(&path) for an inventoried legacy audit source; the path is missing, so the error is thrown with the alias and path.

Common situations: The legacy audit directory was deleted by cleanup between inventory and the rejection pass; the migration state file references an alias from a different machine/home; a partial restore removed audit trees but kept the inventory.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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