{"record":{"id":"bfeec6852bd2a30a","repo":"xai-org/grok-build","slug":"acp-response-missing-result-field","errorCode":null,"errorMessage":"ACP response missing result field","messagePattern":"ACP response missing result field","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/codegen/xai-grok-pager/src/worktree_cmd/mod.rs","lineNumber":150,"sourceCode":"}\nasync fn ext_call<T: serde::de::DeserializeOwned>(\n    tx: &xai_acp_lib::AcpAgentTx,\n    method: &str,\n    params: &impl serde::Serialize,\n) -> Result<T> {\n    let req =\n        ext_request(method, params).map_err(|e| anyhow::anyhow!(\"failed to build request: {e}\"))?;\n    let resp = acp_send(req, tx)\n        .await\n        .map_err(|e| anyhow::anyhow!(\"{e}\"))?;\n    let envelope: ExtEnvelope<T> = serde_json::from_str(resp.0.get())\n        .map_err(|e| anyhow::anyhow!(\"response parse error: {e}\"))?;\n    if let Some(err) = envelope.error {\n        bail!(\"ACP error: {err}\");\n    }\n    envelope\n        .result\n        .ok_or_else(|| anyhow::anyhow!(\"ACP response missing result field\"))\n}\nasync fn cmd_list(\n    tx: &xai_acp_lib::AcpAgentTx,\n    repo: Option<String>,\n    types: Vec<String>,\n    json: bool,\n    all: bool,\n) -> Result<()> {\n    let records: Vec<WorktreeRecord> = ext_call(\n        tx,\n        \"x.ai/git/worktree/list\",\n        &serde_json::json!({\n            \"repo\": repo,\n            \"type\": types,\n            \"includeAll\": all,\n        }),\n    )\n    .await?;","sourceCodeStart":132,"sourceCodeEnd":168,"githubUrl":"https://github.com/xai-org/grok-build/blob/bc7f02eddd3d84085849dc19ed216f11c23b0571/crates/codegen/xai-grok-pager/src/worktree_cmd/mod.rs#L132-L168","documentation":"Raised by `ext_call` when the parsed ACP envelope contains neither an `error` nor a `result` field — a structurally valid response with no payload. The ACP extension contract requires one of the two; receiving neither means the agent sent an incomplete or protocol-violating reply.","triggerScenarios":"Agent implementation responds with an empty object or an envelope that omits both `result` and `error`; an intermediary drops the payload; agent acknowledges the method without producing a result (notification-style reply to a request).","commonSituations":"Bug in the agent's extension handler that returns early without setting a result; misconfigured agent that treats extension requests as notifications; protocol version mismatch where the request id is reused for a notification.","solutions":["Check the agent's handler for the corresponding extension method and ensure it always sets either result or error.","Verify you are sending a request (with id), not a notification, so the agent replies with a full response.","Confirm agent and CLI agree on the same ACP extension protocol version.","Add a fallback in the caller to treat None result as an empty/default value if the method legitimately may return no payload."],"exampleFix":"// before\nlet info: WorktreeInfo = ext_call(tx, \"worktree/show\", &params).await?;\n// after\nlet info: Option<WorktreeInfo> = ext_call(tx, \"worktree/show\", &params).await\n    .ok() // or change ext_call to map missing result to None for this method","handlingStrategy":"fallback","validationCode":null,"typeGuard":"fn has_payload(v: &serde_json::Value) -> bool {\n    v.get(\"result\").is_some() || v.get(\"error\").is_some()\n}","tryCatchPattern":"let info: Result<WorktreeInfo> = ext_call(tx, \"worktree/show\", &params).await;\nmatch info {\n    Ok(v) => use(v),\n    Err(e) if e.to_string().contains(\"missing result field\") => {\n        // treat as empty/default result for methods that may legitimately return nothing\n        use(WorktreeInfo::default());\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Ensure agent extension handlers always set either result or error on requests.","Use request (with id) semantics, not notifications, for ext_call methods.","Document per-method whether an empty result is legal and handle it in the caller."],"tags":["rust","acp","protocol","json-rpc","missing-field"],"backgroundTag":"response-missing-result-field","analyzedSha":"bc7f02eddd3d84085849dc19ed216f11c23b0571","analyzedAt":"2026-08-31T04:59:42.031Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}