astrid-runtime/astrid · error
cannot load capsule ' ' for unadmitted principal
Error message
cannot load capsule '{id}' for unadmitted principal '{principal}': {error} What it means
Thrown when loading a capsule requires resolving the owner's UID via `principal_directory.uid_for`, and that lookup fails for the given principal. The message names the capsule id and principal, indicating the principal is not admitted (or the directory lookup failed), so the capsule cannot be loaded for them. The directory error is embedded as `{error}`.
Solutions
- Admit the principal via the principal_directory before loading its capsules.
- Confirm you are passing the owning principal, not a different authenticated identity.
- Check the embedded `{error}` to distinguish unadmitted principal from backend failure.
- If the principal was revoked, re-run admission or use the current owner's identity.
Example fix
// before
let view = kernel.load_capsule(&id, &some_principal)?;
// after
let admitted = kernel.principal_directory().uid_for(&some_principal).is_ok();
anyhow::ensure!(admitted, "principal must be admitted before loading capsule {id}");
let view = kernel.load_capsule(&id, &some_principal)?; Defensive patterns
Strategy: validation
Validate before calling
// guard before loading
if principal_directory.uid_for(&principal).is_err() {
anyhow::bail!("admit principal {principal:?} before loading capsule '{id}'");
} Type guard
fn can_load(dir: &PrincipalDirectory, p: &Principal) -> bool { dir.uid_for(p).is_ok() } Try / catch
match load_capsule(id, principal) {
Err(e) if e.to_string().contains("unadmitted principal") => admit_then_retry(principal)?,
other => other,
} Prevention
- Complete principal admission before any capsule load.
- Use the owning principal's identity for capsule operations.
- Re-check admission after revocation or identity changes.
When it happens
Trigger: Calling the capsule-load API with a principal that was never admitted to the principal_directory, or whose directory lookup errors (removed principal, backend failure).
Common situations: Loading a capsule under a different identity than the one that owns it; principal revoked after admission; directory storage misconfiguration or corruption; passing a raw/invalid principal identifier.
Understand the failure class
Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.
Related errors
- an incomplete capsule authority update exists at
- authoritative principal store is unavailable
- cannot remove capsule authority while an install…
- capsule ' ' failed to load
- capsule ' ' has no source directory
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/36847477e53469a2.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:1868
capsule.publish();
}
Ok(())
}
fn runtime_principal_uid(
&self,
system_runtime: bool,
principal: &PrincipalId,
id: &astrid_capsule_types::CapsuleId,
) -> Result<Option<astrid_core::identity::PrincipalUid>, anyhow::Error> {
if system_runtime {
return Ok(None);
}
self.principal_directory
.uid_for(principal)
.map(Some)
.map_err(|error| {
anyhow::anyhow!(
"cannot load capsule '{id}' for unadmitted principal '{principal}': {error}"
)
})
}
/// Build and load one mutable runtime. `Some(principal)` installs that
/// principal's concrete KV/home/env authority from construction onward.
/// `None` is reserved for an explicitly classified `SystemResident` service
/// and receives a neutral system namespace rather than `default` authority.
///
/// # Errors
///
/// Returns an error if the capsule cannot be created, the KV scope cannot be
/// built, or `capsule.load` fails.
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
async fn build_capsule_runtime(
&self,
manifest: astrid_capsule_types::manifest::CapsuleManifest,View on GitHub (pinned to affd8760f4)