{"record":{"id":"7a4c2e4a28da1f43","repo":"astrid-runtime/astrid","slug":"capsule-id-not-found-in-registry","errorCode":null,"errorMessage":"capsule '{id}' not found in registry","messagePattern":"capsule '(.+?)' not found in registry","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":2122,"sourceCode":"    /// or [`RestartOutcome::OldInstanceLingering`] when another `Arc` still\n    /// holds its already-cancelled resources.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if the capsule has no source directory, cannot be\n    /// unregistered, or fails to reload.\n    #[cfg(not(all(target_arch = \"wasm32\", target_os = \"unknown\")))]\n    async fn restart_capsule(\n        &self,\n        id: &astrid_capsule_types::CapsuleId,\n        principal: &PrincipalId,\n        expected_runtime: Option<&astrid_capsule::registry::RuntimeId>,\n    ) -> Result<RestartOutcome, anyhow::Error> {\n        let (source_dir, current_runtime) = {\n            let registry = self.capsules.read().await;\n            let capsule = registry\n                .get_for(principal, id)\n                .ok_or_else(|| anyhow::anyhow!(\"capsule '{id}' not found in registry\"))?;\n            let runtime_id = registry\n                .runtime_id_for(principal, id)\n                .ok_or_else(|| anyhow::anyhow!(\"capsule '{id}' not found in registry\"))?;\n            if expected_runtime.is_some_and(|expected| expected != &runtime_id) {\n                return Ok(RestartOutcome::Superseded);\n            }\n            let source_dir = capsule\n                .source_dir()\n                .map(std::path::Path::to_path_buf)\n                .ok_or_else(|| anyhow::anyhow!(\"capsule '{id}' has no source directory\"))?;\n            (source_dir, runtime_id)\n        };\n\n        // Prepare and prove a route-gated replacement while the current\n        // generation remains visible and healthy. A preparation or readiness\n        // failure leaves the running view untouched.\n        let mut prepared = self\n            .prepare_runtime_replacement(id, &source_dir, principal, current_runtime.key().scope())","sourceCodeStart":2104,"sourceCodeEnd":2140,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L2104-L2140","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nkernel.restart_capsule(&principal, \"my-capsule\", None).await?; // Err: not in registry\n// after\nif kernel.capsule_registered(&principal, \"my-capsule\").await {\n    kernel.restart_capsule(&principal, \"my-capsule\", None).await?;\n} else {\n    kernel.load_capsule_for(&principal, \"my-capsule\").await?;\n}","handlingStrategy":"try-catch","validationCode":"let registered = kernel.capsules()\n    .read().await\n    .get_for(principal, id)\n    .is_some();\nif !registered { return Err(anyhow!(\"capsule {id} not registered for principal\")); }","typeGuard":"fn is_registered(entry: &Option<CapsuleEntry>) -> bool {\n    entry.is_some()\n}","tryCatchPattern":"match kernel.restart_capsule(principal, id, expected).await {\n    Err(e) if e.to_string().contains(\"not found in registry\") => {\n        // fallback: load/install the capsule, then retry once\n    },\n    other => other?,\n}","preventionTips":["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"],"tags":["rust","registry","capsule","not-found"],"backgroundTag":"entity-not-found","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"}