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

  1. Admit the principal via the principal_directory before loading its capsules.
  2. Confirm you are passing the owning principal, not a different authenticated identity.
  3. Check the embedded `{error}` to distinguish unadmitted principal from backend failure.
  4. 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

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


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)