AskUserQuestion: custom freeform response drops the entire structured answers map — multi-question option picks are lost
Summary
When a multi-question AskUserQuestion is answered with a mix of option picks and a custom freeform answer, the resulting tool result contains only the freeform text — every structured answer (the option picks) is silently dropped from what the model sees. The model then re-asks the "unanswered" questions.
Observed on Claude Code CLI 2.1.251 (also present in the SDK-bundled binary 2.1.246 used by the Claude Agent SDK).
Repro
A client drives the SDK with an AskUserQuestionOutput containing BOTH answers (structured map) and response (freeform text):
// AskUserQuestionOutput as sent to the SDK
{
questions: [q1, q2],
answers: {
"q1 text": "Rename Board mode: WorldScreen → BoardScreen (Recommended)", // option pick
"q2 text": "Make it so that if the user dies mid-run, it will award pro-rated rewards" // custom
},
response: "Make it so that if the user dies mid-run, it will award pro-rated rewards"
}
The tool result the model receives:
The user responded: Make it so that if the user dies mid-run, it will award pro-rated rewards
The structured answers map — including the q1 option pick — is absent. The model never learns q1 was answered and re-asks it.
When the same call is made WITHOUT the response field, the tool result correctly shows the full map:
Your questions have been answered: "q1"="...", "q2"="...". You can now continue with these answers in mind.
Root cause (from the CLI binary)
The CLI's AskUserQuestion result builder applies precedence: if the freeform response field is present, it renders The user responded: ${response} and discards the answers map entirely; the map branch (Your questions have been answered: ...) runs only when response is absent. Extracted from the bundled claude binary (2.1.246):
else if (n?.trim()) a = `The user responded: ${n}`;
else if (i) a = (answers-validity-check) ? `Your questions have been answered: ${i}...` : `The user answered: ${i}...`;
A response should be in addition to the structured answers (it is the freeform text for one of the questions), not a replacement for the whole map.
Expected behavior
With both answers and response present, the tool result should carry BOTH: the full question→answer map (including option picks) plus the freeform response — e.g. Your questions have been answered: "q1"="<pick>", "q2"="<custom text>". (the response text is already represented inside the map, so dropping the standalone response branch, or merging it into the map, fixes the loss).
Context
- This surfaced through the Tether agent dashboard (TheMrClaus/tether-tracker-private#16), where a user answered a 2-question ask with one option pick + one custom answer; the option pick vanished and the agent re-asked the question.
- Same symptom class as the VSCode-extension question flow, but this is CLI/SDK headless mode via
updatedInput.answersoncanUseTool/request_user_dialog. - Freeform answers work fine in single-question asks (the map and response carry the same text), so this only bites multi-question asks — easy to miss in testing.