astrid-runtime/astrid · error
replacement manifest id
Error message
replacement manifest id '{}' does not match running capsule '{id}' What it means
Before performing a live replacement, the kernel loads the Capsule.toml from the prepared source directory and checks that its `package.name` equals the id of the running capsule being replaced. A mismatch means the source materialization belongs to a different capsule and replacing would silently swap in unrelated code.
Solutions
- Make the Capsule.toml `package.name` match the id passed to the replacement call.
- Pass the correct source_dir belonging to the running capsule.
- If the capsule was renamed, unload the old capsule and load the new one instead of a live replacement.
Example fix
# before (Capsule.toml) [package] name = "my-capsule-v2" # after [package] name = "my-capsule" # must match the running capsule id
Defensive patterns
Strategy: validation
Validate before calling
let manifest = astrid_capsule::discovery::load_manifest(&source_dir.join("Capsule.toml"))?;
assert_eq!(manifest.package.name, id.as_str(), "replacement source belongs to a different capsule"); Try / catch
if let Err(e) = kernel.prepare_replacement(id, &source_dir).await {
if e.to_string().contains("does not match running capsule") {
return Err(anyhow!("check source_dir: {} points at a different capsule", source_dir.display()));
}
return Err(e);
} Prevention
- Derive source_dir from the capsule id instead of hardcoding paths.
- Keep capsule renames paired with unload/load, not live replacement.
- Verify Capsule.toml package.name in CI per workspace member.
When it happens
Trigger: Calling the replace/reload-preparation API for capsule `{id}` with a `source_dir` whose Capsule.toml declares a different `package.name` (e.g., the directory was repointed at another capsule's checkout).
Common situations: Pointing the replacement path at the wrong workspace member; renaming a capsule in Capsule.toml while the kernel still references the old id; copying the wrong runtime directory over the source of truth.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- cannot replace capsule
- capsule ' ' cannot change runtime scope during live…
- capsule source disappeared while preparing replacement
- legacy capsule directory
- live replacement of stdio MCP capsule
AI-assisted analysis of astrid-runtime/astrid@affd8760f4 (2026-09-09).
Data as JSON: /api/errors/6ff0fa7f14990d08.
Report an issue: GitHub.
Appendix: source
Thrown at crates/astrid-kernel/src/lib.rs:2006
capsule_adversarial_tests::record_workspace_source(&capsule_name, &ctx.workspace_source);
capsule.load(&ctx).await?;
Ok(capsule)
}
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
async fn prepare_runtime_replacement(
&self,
id: &astrid_capsule_types::CapsuleId,
source_dir: &Path,
principal: &PrincipalId,
expected_scope: astrid_capsule::registry::RuntimeScope,
) -> Result<PreparedRuntimeReplacement, anyhow::Error> {
self.verify_workspace_capsule_tree(source_dir)?;
let manifest_path = source_dir.join("Capsule.toml");
let manifest = astrid_capsule::discovery::load_manifest(&manifest_path)
.map_err(|error| anyhow::anyhow!(error))?;
if manifest.package.name != id.as_str() {
anyhow::bail!(
"replacement manifest id '{}' does not match running capsule '{id}'",
manifest.package.name
);
}
let bound = self.capture_bound_materialization(
source_dir,
principal,
&manifest,
"replacement source",
)?;
let runtime_dir = bound.as_ref().map_or_else(
|| source_dir.to_path_buf(),
|bound| bound.runtime_dir.clone(),
);
let manifest = bound
.as_ref()
.map_or_else(|| manifest, |bound| bound.manifest.clone());
let manifest_path = runtime_dir.join("Capsule.toml");View on GitHub (pinned to affd8760f4)