{"record":{"id":"9da79ae6af017fd7","repo":"astrid-runtime/astrid","slug":"live-replacement-of-stdio-mcp-capsule-id-is-no","errorCode":null,"errorMessage":"live replacement of stdio MCP capsule '{id}' is not yet atomic; restart the daemon to activate these process changes","messagePattern":"live replacement of stdio MCP capsule '(.+?)' is not yet atomic; restart the daemon to activate these process changes","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-kernel/src/lib.rs","lineNumber":2027,"sourceCode":"            );\n        }\n        let bound = self.capture_bound_materialization(\n            source_dir,\n            principal,\n            &manifest,\n            \"replacement source\",\n        )?;\n        let runtime_dir = bound.as_ref().map_or_else(\n            || source_dir.to_path_buf(),\n            |bound| bound.runtime_dir.clone(),\n        );\n        let manifest = bound\n            .as_ref()\n            .map_or_else(|| manifest, |bound| bound.manifest.clone());\n        let manifest_path = runtime_dir.join(\"Capsule.toml\");\n        self.verify_workspace_component_paths(&runtime_dir, &manifest)?;\n        if !manifest.mcp_servers.is_empty() {\n            anyhow::bail!(\n                \"live replacement of stdio MCP capsule '{id}' is not yet atomic; restart the daemon to activate these process changes\"\n            );\n        }\n        let artifact = capsule_instance_hash(&manifest, &runtime_dir);\n        let system_allowed = self.system_capsules.read().await.contains(id.as_str());\n        let system_runtime = classify_runtime_residency(&manifest, id, system_allowed)?.is_system();\n        if system_runtime && !manifest.mcp_servers.is_empty() {\n            anyhow::bail!(\n                \"system-resident capsule '{id}' cannot host principal-bearing stdio MCP servers\"\n            );\n        }\n        // Replacement authority is the authenticated operator classification\n        // and installed receipt, never the ancestry of `source_dir`.\n        let actual_scope = if system_runtime {\n            astrid_capsule::registry::RuntimeScope::SystemResident\n        } else {\n            astrid_capsule::registry::RuntimeScope::Principal(\n                self.principal_directory.uid_for(principal)?,","sourceCodeStart":2009,"sourceCodeEnd":2045,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-kernel/src/lib.rs#L2009-L2045","documentation":"Live (in-place) replacement cannot atomically swap out stdio MCP server child processes; restarting the daemon is required to apply manifest changes that affect MCP processes. The kernel deliberately refuses rather than performing a partially-applied, non-atomic update.","triggerScenarios":"Invoking the live replacement API on a capsule whose (bound) manifest still declares one or more `mcp_servers` entries.","commonSituations":"Hot-reloading a capsule during development after adding or editing MCP server definitions; CI applying manifest updates to a running daemon with MCP servers.","solutions":["Restart the daemon so the new capsule (with its MCP processes) activates cleanly.","Unload and reload the capsule instead of live replacement.","If no MCP change is intended, revert the `mcp_servers` section before replacing."],"exampleFix":"// before\nkernel.prepare_runtime_replacement(id, source_dir).await?; // fails: has mcp_servers\n// after\ndaemon.restart().await?; // applies mcp_servers changes atomically","handlingStrategy":"validation","validationCode":"let manifest = astrid_capsule::discovery::load_manifest(&runtime_dir.join(\"Capsule.toml\"))?;\nif !manifest.mcp_servers.is_empty() {\n    return Err(anyhow!(\"mcp_servers present; full daemon restart required\"));\n}","typeGuard":null,"tryCatchPattern":"match kernel.replace_runtime(id, &source_dir).await {\n    Err(e) if e.to_string().contains(\"not yet atomic\") => daemon.restart().await,\n    other => other,\n}","preventionTips":["Treat mcp_servers changes as restart-required deployments.","Split MCP servers into separate capsules to keep core capsules hot-reloadable.","Detect mcp_servers diffs in CI and schedule restarts."],"tags":["mcp-servers","live-replacement","unsupported-operation"],"backgroundTag":"unsupported-operation","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"}