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

Unsupported

Unsupported

Error message

legacy principal {alias} (uid {uid}) retains unsupported {name} state; no authoritative migration API exists: {}

What it means

Thrown by ensure_no_unretired_component_sources when a legacy principal retains non-empty kv/ or tokens/ state in its old home. These components have no authoritative migration API, so the kernel cannot convert the data; it fails with io::ErrorKind::Unsupported instead of silently dropping it.

Source

Thrown at crates/astrid-kernel/src/legacy_migration_barrier/mod.rs:832

                ),
            ));
        }
    }
    for (alias, uid) in directory.bindings() {
        let root = home.principal_home(&alias).root().to_path_buf();
        if !path_exists(&root)? {
            continue;
        }
        let unsupported = [
            ("kv", home.principal_home(&alias).kv_dir()),
            ("tokens", home.principal_home(&alias).tokens_dir()),
        ];
        for (name, path) in unsupported {
            if !path_exists(&path)? {
                continue;
            }
            if snapshot_path(&path)?.entries != 0 {
                return Err(io::Error::new(
                    io::ErrorKind::Unsupported,
                    format!(
                        "legacy principal {alias} (uid {uid}) retains unsupported {name} state; no authoritative migration API exists: {}",
                        path.display()
                    ),
                ));
            }
            if allow_empty_cleanup {
                retire_empty_directory(&path)?;
            } else {
                return Err(io::Error::new(
                    io::ErrorKind::InvalidData,
                    format!(
                        "legacy {name} source reappeared after cut-over: {}",
                        path.display()
                    ),
                ));
            }

View on GitHub (pinned to affd8760f4)

Solutions

  1. Manually export/archive the kv/ and tokens/ contents, then empty the directories before re-running cut-over.
  2. Confirm no component still writes to these directories (stop legacy agents) and clear the data.
  3. If the state is obsolete, delete the non-empty legacy kv/tokens directories after backing them up.
  4. Escalate/feature-request an authoritative migration path if the data must be preserved in v2.

Example fix

// before
cut_over(...)?; // Unsupported: kv/ has 37 entries, no migration API
// after
archive_dir(principal_home.kv_dir(), "/backup/alice-kv")?;
archive_dir(principal_home.tokens_dir(), "/backup/alice-tokens")?;
// directories now empty -> cut-over proceeds
Defensive patterns

Strategy: validation

Validate before calling

for dir in [home.principal_home(&alias).kv_dir(), home.principal_home(&alias).tokens_dir()] {
    if path_exists(&dir)? && snapshot_path(&dir)?.entries != 0 {
        // archive/export manually — no automatic migration exists
    }
}

Type guard

fn unsupported_state_empty(home: &AstridHome, alias: &PrincipalId) -> io::Result<bool> {
    let p = home.principal_home(alias);
    Ok(!path_exists(p.kv_dir())? && !path_exists(p.tokens_dir())?)
}

Try / catch

match cut_over(&home, &dir) {
    Err(e) if e.kind() == io::ErrorKind::Unsupported => {
        archive_and_clear_unsupported_state(&home)?;
        retry_cut_over()?;
    }
    other => other?,
}

Prevention

When it happens

Trigger: Cut-over verification finds <principal-home>/kv/ or <principal-home>/tokens/ present with snapshot.entries != 0 for any bound principal alias.

Common situations: Principal actively used legacy KV or token storage that the current migration pipeline never supported; long-idle principal whose legacy state was never cleaned; operator assumed empty-dir cleanup would suffice but data remained.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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