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
- Read `{msg}` for the exact serde/deserialization failure and compare the client's response payload against the expected `UserQuestionResponse` schema.
- Upgrade or fix the client so its reply matches the current schema (accepted answers + annotations, ChatAboutThis, SkipInterview, or Cancelled).
- Check for version skew between agent and client after a protocol update; align both to the same version.
- 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
- Keep client and server protocol versions in lockstep
- Generate client response types from the shared schema
- Log raw client replies when deserialization fails
- Add conformance tests for the user-question response format
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
- Failed to parse billing data: {e}
- response parse error: {e}
- <serde_json deserialization error for summary.json>
- Failed to create agent config: {e}
- --permission-mode: invalid value: {e}
AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31).
Data as JSON: /api/errors/07c58a86649fc60d.
Report an issue: GitHub.