You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
question tool: SchemaError "Missing key at [\"questions\"][0][\"question\"]" — required field should be optional / fall back to header #28438
The AskUserQuestion / question tool fails synchronously with
SchemaError(Missing key at ["questions"][0]["question"])
when the model returns a question item that includes header + options but omits the inner question (long-form prompt) field. The tool call wrapper does not catch the throw, so the whole assistant turn errors out and the session becomes unusable until restarted.
This is reproducible against v1.14.50 and the schema is unchanged in v1.14.49 and v1.14.51, so upgrading does not help. The lax-decode fix in 397ee419d (~Jan 2026) is post-window.
Reproduction
Any prompt template / model that emits a question item like:
…will trigger the throw at decode time. Observed in real sessions against two unrelated projects (kestra-software-reports, agent-installation-troubleshooting) on v1.14.50.
Root cause
packages/opencode/src/question/index.ts:23 declares question as required:
Schema.decodeUnknownSync throws immediately on the missing key. The tool dispatcher does not wrap this in a try/catch, so the assistant turn ends with an unhandled SchemaError.
Diff window
$ git log --oneline v1.14.49..v1.14.51 -- packages/opencode/src/question/
(no commits)
Schema is byte-identical across the range. No upstream PR addresses this.
Proposed fix (two-line patch)
- question: Schema.String.annotate({ description: "Complete question" }),+ question: Schema.optional(Schema.String).annotate({ description: "Complete question (defaults to header if omitted)" }),
…plus a one-line renderer fallback in packages/opencode/src/cli/cmd/tui/routes/session/question.tsx to display question ?? header.
This matches the lax-decode direction already taken in 397ee419d (later commit) and is structurally non-breaking (Effect Schema Schema.optional is a pure relaxation).
Why not just fix the model prompt?
The user has no control over which model emits the request, and the symptom appears across multiple model backends. A two-line server-side relaxation is the right defense-in-depth — the inner question is genuinely redundant when header already carries the prompt.
Environment
opencode v1.14.50
macOS 14, tmux 3.4
Encountered in 2 independent sessions in the same week
Related
Lax-decode commit 397ee419d (post-window) shows the maintainers' direction
No existing issue with text SchemaError question was found at time of filing
I looked into this and can confirm the bug. Here's what I found:
Root cause
Question.Prompt inherits from base in packages/opencode/src/question/index.ts, where question is declared as Schema.String (required). When the tool is invoked by the model without the question field, Schema.decodeUnknownSync throws synchronously at line 149 — uncaught — crashing the assistant turn.
If question were made optional, this would render "undefined"=... in the tool result. It should fall back to q.header.
And a third: the TUI renderer
packages/opencode/src/cli/cmd/tui/routes/session/question.tsx:348 renders {question()?.question} — if question is undefined, the prompt text is silently blank.
Proposed fix (3 lines across 3 files)
question/index.ts — make question optional in base:
Same root cause, mirror direction — got Missing key at ["questions"][0]["header"]
on GPT-5.5 (works fine on claude-opus-4-7). The proposed two-line Schema.optional
relaxation should be applied symmetrically to header as well, not just question.
Activity
21pounder commentedon May 20, 2026
I looked into this and can confirm the bug. Here's what I found:
Root cause
Question.Promptinherits frombaseinpackages/opencode/src/question/index.ts, wherequestionis declared asSchema.String(required). When the tool is invoked by the model without thequestionfield,Schema.decodeUnknownSyncthrows synchronously at line 149 — uncaught — crashing the assistant turn.I reproduced it locally with a minimal script:
Output:
There's also a second affected site
packages/opencode/src/tool/question.ts:31formats the output string usingq.questiondirectly:If
questionwere made optional, this would render"undefined"=...in the tool result. It should fall back toq.header.And a third: the TUI renderer
packages/opencode/src/cli/cmd/tui/routes/session/question.tsx:348renders{question()?.question}— ifquestionisundefined, the prompt text is silently blank.Proposed fix (3 lines across 3 files)
question/index.ts— makequestionoptional inbase:tool/question.ts:31— fall back toheaderin the formatted output:tui/routes/session/question.tsx:348— fall back toheaderin the renderer:I'd like to take this if it's not already being worked on.
Screenshots
wanggan768q commentedon May 20, 2026
+1
Same root cause, mirror direction — got
Missing key at ["questions"][0]["header"]on GPT-5.5 (works fine on claude-opus-4-7). The proposed two-line
Schema.optionalrelaxation should be applied symmetrically to
headeras well, not justquestion.fix(question): surface schema failures as friendly tool errors (#28438)
21pounder commentedon May 21, 2026
Thanks for the cleaner approach @kitlangton — hardening the decode boundary is the right call. Happy to close this in favor of #28563.