astrid-runtime/astrid · error
unknown migration component name: {name}
Error message
unknown migration component name: {name} What it means
`validate_component_name` enforces the canonical naming scheme for migration ledger components. A name must either be one of the known `system:*` components or a `principal:<uid>:<kind>` name with at least three colon-separated parts starting with `principal`. This error is thrown when the name matches neither form, so the ledger contains a component the library does not recognize.
Source
Thrown at crates/astrid-kernel/src/legacy_migration_barrier/ledger.rs:546
}
Ok(())
}
fn validate_component_name(name: &str) -> io::Result<()> {
match name {
"system:state-db"
| "system:cow"
| "system:invites"
| "system:pair-tokens"
| "system:gateway-revocations"
| "system:host-secrets"
| "system:capsule-authority"
| "system:fresh-layout" => return Ok(()),
_ => {},
}
let parts = name.split(':').collect::<Vec<_>>();
if parts.len() < 3 || parts[0] != "principal" {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("unknown migration component name: {name}"),
));
}
PrincipalUid::from_str(parts[1]).map_err(|_| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("migration component has a non-canonical principal UID: {name}"),
)
})?;
let valid_shape = match parts[2] {
"home" | "profile" | "capsules" | "secrets" | "audit" | "logs" | "tmp" | "distro-lock"
| "distro-init" => parts.len() == 3,
"env" | "secret" => parts.len() == 4 && !parts[3].is_empty(),
_ => false,
};
if !valid_shape {
return Err(io::Error::new(View on GitHub (pinned to affd8760f4)
Solutions
- Correct the component name in the ledger to the canonical form `principal:<uid>:<kind>` (kind one of home|profile|capsules|secrets|audit|logs|tmp|distro-lock|distro-init, or env/secret with an extra non-empty segment).
- If the component is a system component, use the exact registered name (e.g. `system:state-db`, `system:cow`, `system:invites`, `system:pair-tokens`, `system:gateway-revocations`, `system:host-secrets`, `system:capsule-authority`, `system:fresh-layout`).
- Rebuild the ledger through the library's write path instead of editing JSON by hand.
- Ensure the tool that produced the ledger is the same version as the library validating it.
Example fix
// before
{"name": "home", ...}
// after
{"name": "principal:01H8X7Y3Z9Q:home", ...} Defensive patterns
Strategy: validation
Validate before calling
// Validate component names before handing a ledger to the library
fn is_valid_component_name(name: &str) -> bool {
const SYSTEM: [&str; 8] = ["system:state-db","system:cow","system:invites","system:pair-tokens",
"system:gateway-revocations","system:host-secrets","system:capsule-authority","system:fresh-layout"];
if SYSTEM.contains(&name) { return true; }
let parts: Vec<&str> = name.split(':').collect();
parts.len() >= 3 && parts[0] == "principal"
} Type guard
fn is_principal_component(name: &str) -> Option<(&str, &str)> {
let parts: Vec<&str> = name.split(':').collect();
if parts.len() >= 3 && parts[0] == "principal" { Some((parts[1], parts[2])) } else { None }
} Prevention
- Always build component names with the library's helpers, never string concatenation in scripts
- Use `principal:<canonical-uid>:<kind>` with a kind from the documented set
- Never hand-edit ledger JSON; use write_ledger
- Pin the tool version used to write ledgers to the library version validating them
When it happens
Trigger: Calling `validate_ledger_shape` (via `write_ledger` or any ledger decode path) with a `MigrationLedger` whose `components` array contains a name like `"home"`, `"state"`, `"misc:foo"`, or a `principal:...` name split into fewer than 3 parts (e.g. `"principal:01HABC"`).
Common situations: Hand-editing the ledger JSON and mistyping a component name; a script generating ledger entries with the wrong prefix; a ledger written by an incompatible/newer tool version using unknown component names.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- corpus label must contain only lowercase ASCII letters, digi
- migration component has a non-canonical principal UID: {name
- migration ledger contains duplicate component: {}
- migration ledger components are not canonically sorted
- present migration source has absent digest: {}
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/6a9eae675073118d.
Report an issue: GitHub.