{"record":{"id":"4ee089a39766ea72","repo":"astrid-runtime/astrid","slug":"daemon-did-not-return-capsule-metadata-for-wit-gc","errorCode":null,"errorMessage":"daemon did not return capsule metadata for WIT GC","messagePattern":"daemon did not return capsule metadata for WIT GC","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/astrid-cli/src/commands/wit.rs","lineNumber":166,"sourceCode":") -> anyhow::Result<HashSet<String>> {\n    let mut marks = query_daemon_marks()?;\n    let workspace_root = std::env::current_dir().ok();\n    marks.extend(collect_marks_in_workspace(\n        home,\n        workspace_root.as_deref(),\n        workspace_layout,\n    )?);\n    Ok(marks)\n}\n\nfn query_daemon_marks() -> anyhow::Result<HashSet<String>> {\n    let request = async {\n        let mut client = crate::socket_client::connect_kernel_for_workspace(None).await?;\n        let response = client\n            .request(astrid_core::kernel_api::KernelRequest::GetCapsuleMetadata)\n            .await?;\n        let astrid_core::kernel_api::KernelResponse::CapsuleMetadata(entries) = response else {\n            anyhow::bail!(\"daemon did not return capsule metadata for WIT GC\")\n        };\n        Ok(entries\n            .into_iter()\n            .flat_map(|entry| entry.wit_hashes)\n            .collect())\n    };\n    if let Ok(handle) = tokio::runtime::Handle::try_current() {\n        tokio::task::block_in_place(|| handle.block_on(request))\n    } else {\n        let runtime = tokio::runtime::Builder::new_current_thread()\n            .enable_all()\n            .build()\n            .context(\"build runtime for daemon WIT metadata\")?;\n        runtime.block_on(request)\n    }\n}\n\nfn collect_marks_in_workspace(","sourceCodeStart":148,"sourceCodeEnd":184,"githubUrl":"https://github.com/astrid-runtime/astrid/blob/affd8760f44190dbdfbec23403f4c4b642c33112/crates/astrid-cli/src/commands/wit.rs#L148-L184","documentation":"query_daemon_marks asks the kernel daemon via KernelRequest::GetCapsuleMetadata for capsule metadata used to collect WIT hashes for garbage collection. The kernel_api enum only treats the CapsuleMetadata variant as valid; any other KernelResponse variant means the daemon misunderstood or mishandled the request, so the code bails with this message.","triggerScenarios":"client.request(KernelRequest::GetCapsuleMetadata) resolves to a KernelResponse variant other than CapsuleMetadata (e.g. an error/ack variant), triggering the let-else bail at wit.rs:166 inside query_daemon_marks, called from collect_marks.","commonSituations":"Daemon running an older/other protocol version that responds with a legacy or error variant; connected to the wrong socket so a different kernel build answers; daemon-side handler for GetCapsuleMetadata not implemented and returns a generic fallback response; transient daemon restart returning an error envelope.","solutions":["Restart/upgrade the astrid daemon so its kernel_api matches the CLI's expectations and returns CapsuleMetadata","Verify you are connecting to the correct workspace kernel socket (connect_kernel_for_workspace(None) resolution)","Check the daemon logs for the handler of KernelRequest::GetCapsuleMetadata failing and returning an error variant","Make the response handling tolerant by matching explicit error variants with clearer messages before the let-else"],"exampleFix":"// before\nlet astrid_core::kernel_api::KernelResponse::CapsuleMetadata(entries) = response else {\n    anyhow::bail!(\"daemon did not return capsule metadata for WIT GC\")\n};\n// after\nmatch response {\n    KernelResponse::CapsuleMetadata(entries) => Ok(entries),\n    other => anyhow::bail!(\"daemon returned {other:?} instead of capsule metadata for WIT GC\"),\n}","handlingStrategy":"try-catch","validationCode":"// after sending GetCapsuleMetadata, check variant before destructuring:\nfn is_capsule_metadata(r: &KernelResponse) -> bool { matches!(r, KernelResponse::CapsuleMetadata(_)) }","typeGuard":"fn as_capsule_metadata(r: KernelResponse) -> Option<Vec<CapsuleMetadataEntry>> { match r { KernelResponse::CapsuleMetadata(e) => Some(e), _ => None } }","tryCatchPattern":"let marks = async { ... }.await.map_err(|e| {\n    eprintln!(\"WIT GC: daemon metadata query failed: {e}; skipping GC marks\");\n    e\n});","preventionTips":["Keep daemon and CLI on matching kernel_api versions","Log the unexpected response variant (Debug) to diagnose protocol drift","Ping the daemon with a version/capability request before feature-specific calls"],"tags":["ipc","daemon","unexpected-response"],"backgroundTag":"unexpected-api-response-shape","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"}