{"record":{"id":"42305138f0ad0bca","repo":"astrid-runtime/astrid","slug":"unsupported","errorCode":"Unsupported","errorMessage":"legacy principal {alias} (uid {uid}) retains unsupported {name} state; no authoritative migration API exists: {}","messagePattern":"legacy principal (.+?) \\(uid (.+?)\\) retains unsupported (.+?) state; no authoritative migration API exists: (.+?)","errorType":"error_code","errorClass":"io::Error","httpStatus":null,"severity":"critical","filePath":"crates/astrid-kernel/src/legacy_migration_barrier/mod.rs","lineNumber":832,"sourceCode":"                ),\n            ));\n        }\n    }\n    for (alias, uid) in directory.bindings() {\n        let root = home.principal_home(&alias).root().to_path_buf();\n        if !path_exists(&root)? {\n            continue;\n        }\n        let unsupported = [\n            (\"kv\", home.principal_home(&alias).kv_dir()),\n            (\"tokens\", home.principal_home(&alias).tokens_dir()),\n        ];\n        for (name, path) in unsupported {\n            if !path_exists(&path)? {\n                continue;\n            }\n            if snapshot_path(&path)?.entries != 0 {\n                return Err(io::Error::new(\n                    io::ErrorKind::Unsupported,\n                    format!(\n                        \"legacy principal {alias} (uid {uid}) retains unsupported {name} state; no authoritative migration API exists: {}\",\n                        path.display()\n                    ),\n                ));\n            }\n            if allow_empty_cleanup {\n                retire_empty_directory(&path)?;\n            } else {\n                return Err(io::Error::new(\n                    io::ErrorKind::InvalidData,\n                    format!(\n                        \"legacy {name} source reappeared after cut-over: {}\",\n                        path.display()\n                    ),\n                ));\n            }","sourceCodeStart":814,"sourceCodeEnd":850,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/legacy_migration_barrier/mod.rs#L814-L850","documentation":"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.","triggerScenarios":"Cut-over verification finds <principal-home>/kv/ or <principal-home>/tokens/ present with snapshot.entries != 0 for any bound principal alias.","commonSituations":"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.","solutions":["Manually export/archive the kv/ and tokens/ contents, then empty the directories before re-running cut-over.","Confirm no component still writes to these directories (stop legacy agents) and clear the data.","If the state is obsolete, delete the non-empty legacy kv/tokens directories after backing them up.","Escalate/feature-request an authoritative migration path if the data must be preserved in v2."],"exampleFix":"// before\ncut_over(...)?; // Unsupported: kv/ has 37 entries, no migration API\n// after\narchive_dir(principal_home.kv_dir(), \"/backup/alice-kv\")?;\narchive_dir(principal_home.tokens_dir(), \"/backup/alice-tokens\")?;\n// directories now empty -> cut-over proceeds\n","handlingStrategy":"validation","validationCode":"for dir in [home.principal_home(&alias).kv_dir(), home.principal_home(&alias).tokens_dir()] {\n    if path_exists(&dir)? && snapshot_path(&dir)?.entries != 0 {\n        // archive/export manually — no automatic migration exists\n    }\n}","typeGuard":"fn unsupported_state_empty(home: &AstridHome, alias: &PrincipalId) -> io::Result<bool> {\n    let p = home.principal_home(alias);\n    Ok(!path_exists(p.kv_dir())? && !path_exists(p.tokens_dir())?)\n}","tryCatchPattern":"match cut_over(&home, &dir) {\n    Err(e) if e.kind() == io::ErrorKind::Unsupported => {\n        archive_and_clear_unsupported_state(&home)?;\n        retry_cut_over()?;\n    }\n    other => other?,\n}","preventionTips":["Inventory legacy kv/ and tokens/ usage across all principals before planning migration.","Archive these directories during decommissioning since no importer exists.","Monitor for new writes to these dirs; treat non-empty kv/tokens as a migration blocker."],"tags":["migration","unsupported","rust","data-loss-risk"],"backgroundTag":"unsupported-operation","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}