{"record":{"id":"019e72a223634001","repo":"astrid-runtime/astrid","slug":"capsule-id-failed-to-load-error","errorCode":null,"errorMessage":"capsule '{id}' failed to load: {error:#}","messagePattern":"capsule '(.+?)' failed to load: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":3108,"sourceCode":"        if registered {\n            if self.capabilities.is_principal_retiring(principal).await {\n                anyhow::bail!(\"cannot reload capsule '{id}' for retiring principal '{principal}'\");\n            }\n            self.restart_capsule(id, principal, None).await?;\n            self.publish_capsules_loaded().await;\n        } else {\n            drop(view_guard);\n            // Build or refresh this principal's view from its installed set.\n            self.ensure_principal_loaded(principal).await;\n            if self.capsules.read().await.get_for(principal, id).is_none()\n                && let Some((_, dir)) = self\n                    .sorted_principal_capsules(principal)\n                    .into_iter()\n                    .find(|(manifest, _)| manifest.package.name == id.as_str())\n            {\n                self.load_capsule(dir, principal)\n                    .await\n                    .map_err(|error| anyhow::anyhow!(\"capsule '{id}' failed to load: {error:#}\"))?;\n            }\n            if self.capsules.read().await.get_for(principal, id).is_none() {\n                return Err(anyhow::anyhow!(\n                    \"capsule '{id}' was not found in the install directories or failed to load\"\n                ));\n            }\n            self.publish_capsules_loaded().await;\n        }\n        Ok(())\n    }\n\n    /// Unload a single capsule by id without a daemon restart.\n    ///\n    /// Mirrors the unregister half of [`Self::restart_capsule`]: it removes the\n    /// capsule from the running registry and explicitly unloads it (there is no\n    /// async `Drop`, so we must do it here to avoid leaking MCP subprocesses and\n    /// other engine resources), then publishes `astrid.v1.capsules_loaded` so the\n    /// tool surface refreshes — the departed capsule self-excludes from the next","sourceCodeStart":3090,"sourceCodeEnd":3126,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L3090-L3126","documentation":"Wrapper error raised when on-demand loading of a capsule from its install directory fails (lib.rs:3108). The kernel found a matching manifest for `id` in the principal's sorted install directories, attempted `load_capsule`, and the underlying load error (compilation, manifest validation, I/O) is chained as `{error:#}`. The original cause is preserved, so read the chained message for the real failure.","triggerScenarios":"Lazily resolving a capsule id during an operation (invoke/restart-style path): a directory matching the id exists under the principal's install dirs, `load_capsule(dir, principal)` returns `Err`, and the error is wrapped at lib.rs:3108.","commonSituations":"Capsule source on disk fails to compile or validate (bad manifest, missing files, syntax errors) after a deploy or manual edit; permission problems reading the install directory; loading a capsule built against an incompatible capsule SDK version.","solutions":["Read the chained `{error:#}` cause to identify the actual load failure and fix that root problem","Validate the capsule's manifest and source in its install directory (fix syntax, missing files, or schema issues)","Reinstall/redeploy the capsule from a known-good package","Check filesystem permissions on the capsule's install directory"],"exampleFix":"// Diagnose the wrapped cause instead of treating it as not-found\nmatch kernel.ensure_capsule_loaded(&principal, &id).await {\n    Err(e) if e.to_string().contains(\"failed to load\") => {\n        // inspect source(&e) for the real compile/manifest error\n        tracing::error!(\"load failure root cause: {:#}\", e);\n    },\n    _ => {},\n}","handlingStrategy":"try-catch","validationCode":"let loadable = capsule_manifest_parses(&install_dir)?\n    && required_source_files_present(&install_dir)?;","typeGuard":null,"tryCatchPattern":"match kernel.ensure_capsule_loaded(principal, id).await {\n    Err(e) if e.to_string().contains(\"failed to load\") => {\n        let root = e.root_cause(); // surface the chained cause to the operator\n        tracing::error!(\"capsule load root cause: {root}\");\n    },\n    other => other?,\n}","preventionTips":["Validate capsule manifests and compile capsules in CI before deployment","Keep capsule SDK versions in sync between build and kernel","Check install-directory permissions after deploys"],"tags":["rust","capsule","load","manifest"],"backgroundTag":"module-init-failed","analyzedSha":"affd8760f44190dbdfbec23403f4c4b642c33112","analyzedAt":"2026-09-09T21:28:12.402Z","contentChangedAt":"2026-09-09T21:28:12.402Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}