anomalyco / anomalyco/opencode

question tool: custom answer option cannot be disabled because "custom" is missing from the Prompt schema

Open
#45,230 1 comment 0 reactions 1 assignee View on GitHub

@nexxeln is already working on this.

Since Aug 26, 2026.

Dominant language
TypeScript
Stars
209k
Forks
27.5k
PR merge metrics
PR metrics pending

Description

Description

The question tool renders a "Type your own answer" option, and the TUI honours a custom: false flag to hide it — but nothing can ever set that flag, because it is missing from the schema the tool accepts.

packages/schema/src/question.ts:

const base = {
  question: ...,
  header: ...,
  options: ...,
  multiple: ...,
}

export const Info = Schema.Struct({
  ...base,
  custom: Schema.Boolean.pipe(optional).annotate({
    description: "Allow typing a custom answer (default: true)",
  }),
}).annotate({ identifier: "QuestionV2.Info" })

export const Prompt = Schema.Struct(base).annotate({ identifier: "QuestionV2.Prompt" })

custom lives on Info. Both tools take Prompt:

  • packages/opencode/src/tool/question.ts:7questions: Schema.mutable(Schema.Array(Question.Prompt))
  • packages/core/src/tool/question.ts:26questions: Schema.Array(QuestionV2.Prompt)

So custom never reaches the JSON schema the model sees, and a custom: false the model emitted anyway would be dropped as an excess property. Grepping the repo, nothing assigns custom anywhere — the only reader is the renderer:

packages/tui/src/routes/session/question.tsx:38

const custom = createMemo(() => question()?.custom !== false)

Since the value is always undefined, custom !== false is always true, and the input is always shown. The Info.custom field, its description, and the !== false guard are all live code for a state that cannot occur.

The tool description compounds it. packages/opencode/src/tool/question.txt:

When custom is enabled (default), a "Type your own answer" option is added automatically; don't include "Other" or catch-all options

"(default)" tells the model this is a setting with a non-default alternative. There is no way to reach it.

Which way to fix it

Two options, and I picked the first:

  1. Move custom into base so it reaches Prompt and the capability the renderer already implements becomes usable. One-line change; Info is unchanged in shape since base is spread into it.
  2. Drop custom from Info, delete the !== false guard, and remove the sentence from both tool descriptions — i.e. admit the option does not exist.

(1) seemed right because the rendering side is complete and correct; only the input schema is missing the field. Happy to switch to (2) if the intent was for custom to be host-controlled rather than model-controlled.

Steps to reproduce
  1. Call the question tool with custom: false on a question.
  2. The "Type your own answer" input is still rendered.
  3. Inspect the tool's JSON schema — custom is not among the accepted properties.
Operating System

Windows 11 (platform independent)

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.