astrid-runtime/astrid · error
capsule ' ' not found in registry
Error message
capsule '{id}' not found in registry What it means
Thrown during a capsule restart when `registry.get_for(principal, id)` finds no capsule entry for that principal/id pair in the in-memory capsule registry. The restart flow needs the live capsule handle to read its source directory, and without a registered entry it cannot proceed.
Solutions
- Verify the capsule id exists for the given principal before restarting (query the registry or list capsules for the principal)
- Load/install the capsule first if it is missing from the registry (the kernel's load path registers it)
- Check that the correct principal is being passed; the registry is keyed per principal
Example fix
// before
kernel.restart_capsule(&principal, "my-capsule", None).await?; // Err: not in registry
// after
if kernel.capsule_registered(&principal, "my-capsule").await {
kernel.restart_capsule(&principal, "my-capsule", None).await?;
} else {
kernel.load_capsule_for(&principal, "my-capsule").await?;
} Defensive patterns
Strategy: try-catch
Validate before calling
let registered = kernel.capsules()
.read().await
.get_for(principal, id)
.is_some();
if !registered { return Err(anyhow!("capsule {id} not registered for principal")); } Type guard
fn is_registered(entry: &Option<CapsuleEntry>) -> bool {
entry.is_some()
} Try / catch
match kernel.restart_capsule(principal, id, expected).await {
Err(e) if e.to_string().contains("not found in registry") => {
// fallback: load/install the capsule, then retry once
},
other => other?,
} Prevention
- Keep capsule ids from a registry listing rather than hardcoding strings
- Key all capsule operations by (principal, id) and verify ownership before restart
- Handle uninstall/stop events so cached ids are invalidated
When it happens
Trigger: Calling the kernel's restart API (restart_capsule-style method at lib.rs:2122) with an `id` that is not registered under the given `principal` — wrong id, wrong principal, or the capsule was previously uninstalled/stopped and removed from the registry.
Common situations: Restarting a capsule after it failed to load at startup (so it never got registered); passing a capsule id that belongs to a different principal (multi-tenant setups); typos or stale ids held by a client after the capsule was unregistered.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- capsule ' ' was not found in the install directories or…
- failed to unregister capsule
- an incomplete capsule authority update exists at
- cannot load capsule ' ' for unadmitted principal
- cannot remove capsule authority while an install…
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/7a4c2e4a28da1f43.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:2122
/// or [`RestartOutcome::OldInstanceLingering`] when another `Arc` still
/// holds its already-cancelled resources.
///
/// # Errors
///
/// Returns an error if the capsule has no source directory, cannot be
/// unregistered, or fails to reload.
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
async fn restart_capsule(
&self,
id: &astrid_capsule_types::CapsuleId,
principal: &PrincipalId,
expected_runtime: Option<&astrid_capsule::registry::RuntimeId>,
) -> Result<RestartOutcome, anyhow::Error> {
let (source_dir, current_runtime) = {
let registry = self.capsules.read().await;
let capsule = registry
.get_for(principal, id)
.ok_or_else(|| anyhow::anyhow!("capsule '{id}' not found in registry"))?;
let runtime_id = registry
.runtime_id_for(principal, id)
.ok_or_else(|| anyhow::anyhow!("capsule '{id}' not found in registry"))?;
if expected_runtime.is_some_and(|expected| expected != &runtime_id) {
return Ok(RestartOutcome::Superseded);
}
let source_dir = capsule
.source_dir()
.map(std::path::Path::to_path_buf)
.ok_or_else(|| anyhow::anyhow!("capsule '{id}' has no source directory"))?;
(source_dir, runtime_id)
};
// Prepare and prove a route-gated replacement while the current
// generation remains visible and healthy. A preparation or readiness
// failure leaves the running view untouched.
let mut prepared = self
.prepare_runtime_replacement(id, &source_dir, principal, current_runtime.key().scope())View on GitHub (pinned to affd8760f4)