xai-org/grok-build · error · ToolError

Client returned an invalid response to user question: {msg}

Error message

Client returned an invalid response to user question: {msg}

What it means

After the client answers a user question, the response is deserialized into `UserQuestionResponse`. `UserQuestionError::MalformedResponse(msg)` means the payload arrived but failed to parse or validate (missing fields, wrong shape, unknown variants), and the tool converts it into this execution error. It signals a contract mismatch between client and server response schemas.

Source

Thrown at crates/codegen/xai-grok-tools/src/implementations/grok_build/ask_user_question/mod.rs:527

            Ok(UserQuestionResponse::SkipInterview {
                questions,
                partial_answers,
            }) => {
                let message = format::format_skip_interview(&questions, &partial_answers);
                Ok(AskUserQuestionOutput::UserAnswered { message })
            }
            Ok(UserQuestionResponse::Cancelled) => Ok(AskUserQuestionOutput::UserAnswered {
                message: unanswered.to_string(),
            }),
            Err(UserQuestionError::TransportError(msg)) => {
                Err(xai_tool_runtime::ToolError::execution(
                    xai_tool_protocol::ToolId::new("ask_user_question").expect("valid"),
                    format!("Failed to reach the client for user question: {msg}"),
                ))
            }
            Err(UserQuestionError::MalformedResponse(msg)) => {
                Err(xai_tool_runtime::ToolError::execution(
                    xai_tool_protocol::ToolId::new("ask_user_question").expect("valid"),
                    format!("Client returned an invalid response to user question: {msg}"),
                ))
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::types::resources::Resources;
    use crate::types::tool_metadata::test_ctx_with_call_id;
    use indexmap::IndexMap;
    use tokio::sync::mpsc;

    fn make_question(question: &str, labels: &[&str]) -> Question {
        Question {
            question: question.to_string(),

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Read `{msg}` for the exact serde/deserialization failure and compare the client's response payload against the expected `UserQuestionResponse` schema.
  2. Upgrade or fix the client so its reply matches the current schema (accepted answers + annotations, ChatAboutThis, SkipInterview, or Cancelled).
  3. Check for version skew between agent and client after a protocol update; align both to the same version.
  4. Capture and log the raw response body on the client side to confirm what is actually being sent.

Example fix

// before: client sends legacy shape
{ "answer": "yes" }
// after: client must send the accepted response shape
{ "type": "accepted", "answers": { "q1": "yes" }, "annotations": {} }
Defensive patterns

Strategy: type-guard

Validate before calling

// validate the client's reply shape before trusting it
function looksLikeUserQuestionResponse(v) {
  return v != null && typeof v === "object" &&
    ["accepted", "chat_about_this", "skip_interview", "cancelled"].includes(v.type);
}

Type guard

fn is_valid_response(v: &serde_json::Value) -> bool {
    serde_json::from_value::<UserQuestionResponse>(v.clone()).is_ok()
}

Try / catch

try {
  const out = await tool("ask_user_question", { questions });
} catch (e) {
  if (String(e.message).startsWith("Client returned an invalid response")) {
    logRawClientReply(); // capture payload for schema debugging
  } else { throw e; }
}

Prevention

When it happens

Trigger: The client sends a reply that does not deserialize into `UserQuestionResponse` — e.g. answers keyed incorrectly, annotations of the wrong type, an unrecognized response variant, or a truncated/null body from a buggy or outdated client.

Common situations: Custom or third-party ACP clients that implement the user-question extension with an outdated/incorrect schema; version skew after a protocol change (e.g. id-keyed answer format added); middleware/proxies rewriting JSON bodies.

Related errors


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