xai-org/grok-build · error

response parse error: {e}

Error message

response parse error: {e}

What it means

Raised by `ext_call` when the ACP response body received from the agent cannot be parsed into the expected `ExtEnvelope<T>` wrapper via serde_json. This means the reply string is not valid JSON or its shape does not match the envelope (missing/misspelled fields, wrong result payload type). It indicates a protocol mismatch between the CLI's expected schema and what the agent actually returned.

Source

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

}
/// ACP extension responses are wrapped in `{ "result": T, "error": ... }`.
#[derive(serde::Deserialize)]
struct ExtEnvelope<T> {
    result: Option<T>,
    error: Option<serde_json::Value>,
}
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!({

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Log the raw `resp.0` string to see exactly what came back and compare with the expected ExtEnvelope schema.
  2. Verify CLI and agent versions match and speak the same ACP extension schema.
  3. Check that the generic T used at each call site matches the actual result payload type for that method.
  4. Fix the Deserialize impl for T (e.g. make new fields #[serde(default)], rename fields to match the agent's output).

Example fix

// before
#[derive(Deserialize)]
struct WorktreeInfo { path: String, branch: String }
// after
#[derive(Deserialize)]
struct WorktreeInfo {
    path: String,
    #[serde(default)]
    branch: Option<String>, // tolerate agents that omit the field
}
Defensive patterns

Strategy: try-catch

Type guard

fn is_valid_envelope(raw: &str) -> bool {
    serde_json::from_str::<serde_json::Value>(raw)
        .ok()
        .map(|v| v.get("result").is_some() || v.get("error").is_some())
        .unwrap_or(false)
}

Try / catch

match ext_call::<WorktreeInfo>(tx, "worktree/show", &params).await {
    Ok(info) => use(info),
    Err(e) if e.to_string().starts_with("response parse error") => {
        eprintln!("agent reply did not match expected schema: {e:#}");
        eprintln!("check CLI/agent version compatibility");
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: The ACP agent returns malformed or non-JSON text on the wire; the agent returns a valid envelope but the embedded `result` does not deserialize into the caller's generic T; a schema/version drift between CLI and agent changes field names or types.

Common situations: Agent upgraded to a newer ACP extension schema while the CLI is older (or vice versa); agent returns an error body without the envelope structure; a proxy/logging layer corrupts the response string.

Understand the failure class

Related errors


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