xai-org/grok-build · error

ACP response missing result field

Error message

ACP response missing result field

What it means

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.

Source

Thrown at crates/codegen/xai-grok-pager/src/worktree_cmd/mod.rs:150

}
async fn ext_call<T: serde::de::DeserializeOwned>(
    tx: &xai_acp_lib::AcpAgentTx,
    method: &str,
    params: &impl serde::Serialize,
) -> Result<T> {
    let req =
        ext_request(method, params).map_err(|e| anyhow::anyhow!("failed to build request: {e}"))?;
    let resp = acp_send(req, tx)
        .await
        .map_err(|e| anyhow::anyhow!("{e}"))?;
    let envelope: ExtEnvelope<T> = serde_json::from_str(resp.0.get())
        .map_err(|e| anyhow::anyhow!("response parse error: {e}"))?;
    if let Some(err) = envelope.error {
        bail!("ACP error: {err}");
    }
    envelope
        .result
        .ok_or_else(|| anyhow::anyhow!("ACP response missing result field"))
}
async fn cmd_list(
    tx: &xai_acp_lib::AcpAgentTx,
    repo: Option<String>,
    types: Vec<String>,
    json: bool,
    all: bool,
) -> Result<()> {
    let records: Vec<WorktreeRecord> = ext_call(
        tx,
        "x.ai/git/worktree/list",
        &serde_json::json!({
            "repo": repo,
            "type": types,
            "includeAll": all,
        }),
    )
    .await?;

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Check the agent's handler for the corresponding extension method and ensure it always sets either result or error.
  2. Verify you are sending a request (with id), not a notification, so the agent replies with a full response.
  3. Confirm agent and CLI agree on the same ACP extension protocol version.
  4. Add a fallback in the caller to treat None result as an empty/default value if the method legitimately may return no payload.

Example fix

// before
let info: WorktreeInfo = ext_call(tx, "worktree/show", &params).await?;
// after
let info: Option<WorktreeInfo> = ext_call(tx, "worktree/show", &params).await
    .ok() // or change ext_call to map missing result to None for this method
Defensive patterns

Strategy: fallback

Type guard

fn has_payload(v: &serde_json::Value) -> bool {
    v.get("result").is_some() || v.get("error").is_some()
}

Try / catch

let info: Result<WorktreeInfo> = ext_call(tx, "worktree/show", &params).await;
match info {
    Ok(v) => use(v),
    Err(e) if e.to_string().contains("missing result field") => {
        // treat as empty/default result for methods that may legitimately return nothing
        use(WorktreeInfo::default());
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: 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).

Common situations: 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.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/bfeec6852bd2a30a. Report an issue: GitHub.