Skip to content

fix(AskUserQuestion): always include questions key and use question text as answer key#191

Open
sudo-yf wants to merge 1 commit into
wxtsky:mainfrom
sudo-yf:fix/askuserquestion-questions-key-and-answer-lookup
Open

fix(AskUserQuestion): always include questions key and use question text as answer key#191
sudo-yf wants to merge 1 commit into
wxtsky:mainfrom
sudo-yf:fix/askuserquestion-questions-key-and-answer-lookup

Conversation

@sudo-yf
Copy link
Copy Markdown

@sudo-yf sudo-yf commented May 24, 2026

Problem

Two bugs in Sources/CodeIsland/AppState.swift cause AskUserQuestion to fail when used through the CodeIsland hook:

Bug 1: H.map undefined crash

askUserQuestionUpdatedInput conditionally set updatedInput["questions"] only when the [[String: Any]] cast succeeded:

if let originalQuestions {
    updatedInput["questions"] = originalQuestions
}

Claude Code's mapToolResultToToolResultBlockParam destructures the hook result as {questions: H, answers: _, annotations: q} and immediately calls H.map(). If the questions key is absent, H is undefined and the call throws:

undefined is not an object (evaluating 'H.map')

Bug 2: All answers returned as empty strings

handleAskUserQuestion built answerKey from the question's header field:

let baseKey = (trimmedHeader?.isEmpty == false ? trimmedHeader : nil) ?? "answer_\(index + 1)"

Claude Code looks up answers by question text: answers[question.question]. Using the header as the dictionary key means every lookup misses, and all answers come back as empty strings.

Fix

Bug 1 — always write the questions key, falling back to the raw toolInput value when the cast fails:

updatedInput["questions"] = originalQuestions ?? (event.toolInput?["questions"] ?? [] as [[String: Any]])

Bug 2 — use questionText as the answer key to match Claude Code's lookup:

let baseKey = questionText

Testing

Verified with a 4-option AskUserQuestion call containing Chinese text in header/label/description fields. Before the fix: crash or empty answers. After: popup renders correctly and all selected answers are returned to Claude Code.

…ext as answer key

Two bugs in the AskUserQuestion round-trip with Claude Code:

1. askUserQuestionUpdatedInput omitted the 'questions' key when
   originalQuestions was nil (cast failure). Claude Code's
   mapToolResultToToolResultBlockParam calls H.map() on questions directly,
   so a missing key causes 'undefined is not an object (evaluating H.map)'.
   Fix: always write questions, falling back to the raw toolInput value.

2. answerKey was derived from the question's header, but Claude Code looks up
   answers by question text (answers[question.question]). The key mismatch
   caused every answer to come back as an empty string.
   Fix: use questionText as the base key instead of header.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants