astrid-runtime/astrid · error
capsule ' ' was not found in the install directories or…
Error message
capsule '{id}' was not found in the install directories or failed to load What it means
Raised after an attempted on-demand load when the capsule is still absent from the registry (lib.rs:3111). Either no directory matching `id` was found in the principal's install directories, or the load was attempted and the capsule still failed to register. It is the definitive 'capsule unavailable' error for the resolve path.
Solutions
- Verify the capsule is installed in the principal's install directories and that the id matches the manifest `package.name` exactly
- Check the install-directory configuration/env so the kernel scans the correct location
- If the capsule exists but fails to load, look for the preceding 'capsule ... failed to load' error for the root cause
- Install the capsule for the principal before invoking it
Example fix
// before
kernel.invoke_capsule(&principal, "my-capsule", input).await?; // Err: not found in install dirs
// after
if !kernel.capsule_installed(&principal, "my-capsule") {
kernel.install_capsule(&principal, capsule_package).await?;
}
kernel.invoke_capsule(&principal, "my-capsule", input).await?; Defensive patterns
Strategy: try-catch
Validate before calling
let installed = install_dirs_for(principal)
.iter()
.any(|d| manifest_name(d) == id);
if !installed { /* install the capsule before invoking */ } Try / catch
match kernel.invoke_capsule(principal, id, input).await {
Err(e) if e.to_string().contains("was not found in the install directories") => {
// distinguish 'not installed' from 'failed to load' via the preceding error
return Err(user_facing_not_found(id));
},
other => other?,
} Prevention
- Install capsules per principal before invoking them; don't assume global installs
- Verify install-directory env/config points at the directory that actually contains the capsule
- Match ids exactly against manifest `package.name` (case-sensitive)
When it happens
Trigger: Invoking or restarting a capsule `id` for a `principal` where (a) no install directory contains a manifest whose `package.name` matches the id, or (b) the load ran but `registry.get_for(principal, id)` still returns `None` afterwards (lib.rs:3111).
Common situations: Typos in capsule ids or querying under the wrong principal; capsule never installed for that principal; install directory misconfigured (wrong ASTRID install path/env); load attempts that fail silently leave the registry empty and surface as this error.
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 ' ' not found in registry
- an incomplete capsule authority update exists at
- cannot load capsule ' ' for unadmitted principal
- cannot remove capsule authority while an install…
- capsule ' ' failed to load
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/16c260f0dce79031.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:3111
}
self.restart_capsule(id, principal, None).await?;
self.publish_capsules_loaded().await;
} else {
drop(view_guard);
// Build or refresh this principal's view from its installed set.
self.ensure_principal_loaded(principal).await;
if self.capsules.read().await.get_for(principal, id).is_none()
&& let Some((_, dir)) = self
.sorted_principal_capsules(principal)
.into_iter()
.find(|(manifest, _)| manifest.package.name == id.as_str())
{
self.load_capsule(dir, principal)
.await
.map_err(|error| anyhow::anyhow!("capsule '{id}' failed to load: {error:#}"))?;
}
if self.capsules.read().await.get_for(principal, id).is_none() {
return Err(anyhow::anyhow!(
"capsule '{id}' was not found in the install directories or failed to load"
));
}
self.publish_capsules_loaded().await;
}
Ok(())
}
/// Unload a single capsule by id without a daemon restart.
///
/// Mirrors the unregister half of [`Self::restart_capsule`]: it removes the
/// capsule from the running registry and explicitly unloads it (there is no
/// async `Drop`, so we must do it here to avoid leaking MCP subprocesses and
/// other engine resources), then publishes `astrid.v1.capsules_loaded` so the
/// tool surface refreshes — the departed capsule self-excludes from the next
/// fan-out. Backs [`astrid_core::kernel_api::KernelRequest::UnloadCapsule`].
///
/// Returns `Ok(true)` if the capsule was loaded and is now unregistered, orView on GitHub (pinned to affd8760f4)