Skip to content

TUI: cannot submit a custom "Type your own answer" in question/ask prompt (Enter swallowed by focused textarea) #30393

Closed

Description

@kristianvast

Summary

In the interactive TUI, when a question (the askuserquestion tool / question.asked flow) offers a "Type your own answer" option, the typed custom answer cannot be submitted. Pressing Enter after typing does nothing — it only inserts newlines into the input box. Selecting one of the predefined options works fine; only the custom free-text path is broken.

Environment

  • opencode v1.15.13 (latest release at time of filing)
  • Linux x86-64, terminal: kitty
  • Reproducible regardless of model/agent — it's a TUI input-handling issue.

Steps to reproduce

  1. In an interactive opencode TUI session, trigger any question that allows a custom answer (custom defaults to true), so the dialog shows numbered options plus a final "Type your own answer" row.
  2. Select "Type your own answer" (it enters edit mode and focuses the text input).
  3. Type some text.
  4. Press Enter to confirm/submit.

Expected

The typed text is submitted as the answer (question.reply), the same way pressing Enter on a predefined option submits it.

Actual

Enter does nothing except add blank lines in the input box. There is no way to confirm/send the custom answer (and no mouse "submit" affordance either). The only escape is Esc to dismiss the question entirely.

Root cause

In the interactive TUI question component, packages/opencode/src/cli/cmd/tui/routes/session/question.tsx (QuestionPrompt):

  • Choosing "Type your own answer" sets store.editing = true and focuses an @opentui/core <textarea> (via val.focus() in the ref).
  • Submission of the typed answer is wired only through the declarative keymap:
useBindings(() => ({
  mode: QUESTION_MODE,
  enabled: store.editing && !confirm(),
  bindings: [
    // ...
    { key: "return", desc: "Submit answer edit", cmd: () => { /* pick(text, true) -> question.reply */ } },
  ],
}))

A focused textarea consumes the Enter keypress itself (newline insertion, up to maxHeight={6}), so the key never reaches the useBindings keymap and the return -> submit binding never fires.

Proof that it's key delivery, not the submit logic: if the binding fired, pick(text, true) would immediately call sdk.client.question.reply(...). It doesn't submit, so the binding is never reached. The only difference between the working option-selection path and the broken custom path is the focused textarea capturing the key.

Why predefined options work but custom doesn't

  • Selecting an option: no textarea is focused, so Enter / number keys flow into the other useBindings block (enabled: !store.editing) and submit normally.
  • Typing a custom answer: the focused textarea swallows Enter before the keymap sees it.

In-repo reference implementation that handles this correctly

The direct-mode footer question UI, packages/opencode/src/cli/cmd/run/footer.question.tsx (RunQuestionBody), handles the identical flow correctly by using a global imperative keyboard handler and explicitly preventing default while editing:

useKeyboard((event) => {
  // ...
  if (cur.editing) {
    if (event.name === "escape") { /* cancel */ return }
    if (event.name === "return" && !event.shift && !event.ctrl && !event.meta) {
      saveCustom()
      event.preventDefault() // stops the focused textarea from eating Enter
    }
    return
  }
  // ...
})

That event.preventDefault() is exactly what the interactive TUI QuestionPrompt is missing.

Suggested fix

Mirror the footer's approach in QuestionPrompt (tui/routes/session/question.tsx): while store.editing is true, intercept Enter at a level that runs before the focused textarea (e.g. a useKeyboard handler), invoke the existing submit logic, and call event.preventDefault(). Reserve Shift+Enter for inserting a newline. The submit logic itself is already present and correct — only key delivery to it is broken.

Notes

  • No existing issue found for this when searching the tracker (custom answer / type your own answer / question submit).
  • Affects the latest release (v1.15.13); the same textarea pattern appears to still be present on main, so this is not fixed by updating.

Permalinks (v1.15.13)

Activity

  1. github-actions commented on Jun 2, 2026

    @github-actions
    Contributor

    This issue might be a duplicate of existing issues. Please check:

    If your issue is specifically and only about Enter being swallowed by the focused textarea (and not the broader dismiss/loop issues in #28112), it may warrant a separate fix, but please review that issue first to see if it covers your case.

  2. rekram1-node commented on Jun 23, 2026

    @rekram1-node
    Contributor

    Automated: closing question issues.

    GitHub Issues are for bug reports and feature requests only — questions / support are no longer tracked here.

    If this is a bug or feature request, please open a new issue with the appropriate template.

  3. rekram1-node commented on Jun 23, 2026

    @rekram1-node
    Contributor

    Reopening – this was incorrectly closed by automated question-issue cleanup. Sorry for the noise.

  4. re1sub commented on Jul 31, 2026

    @re1sub

    Yes. Same exact problem. Any option click should blur the "Type your own answer" input but it doesn't that's why you can't Confirm

  5. ziuus commented on Aug 10, 2026

    @ziuus

    This is fixed by PR #41517 (#41517): it adds target: textareaTarget + priority: 1 to the editing-mode bindings in QuestionPrompt (the DialogPrompt pattern), so the focused textarea routes the return key through the keymap and the submit binding fires instead of Enter being swallowed. It also fixes the same custom-answer input in the CLI direct-mode footer and the web/app question dock.

  6. neriousy commented on Oct 1, 2026

    @neriousy
    Member

    In the OpenCode v2 TUI, question prompts are rendered as session forms, and pressing Enter while typing a custom answer submits it.

    Fixed in #35421.

    Closing as completed. If Enter still doesn't submit a custom answer on v2, please open a new issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions