Skip to content

[Bug]: TUI backspace cannot delete newline characters in composer input #18394

@Hubedge

Description

@Hubedge

Bug Description

In the Hermes TUI composer, newline characters (\n) inserted via any multi-line input mechanism (Shift+Enter, \+Enter, paste) cannot be deleted by the Backspace key. The newlines persist through submission — the agent receives them in the message content, confirming this is a data-level bug, not just a rendering artifact.

Steps to Reproduce

  1. Open Hermes TUI: hermes --tui
  2. Type some text, then insert newlines (any method: Shift+Enter, \+Enter, Ctrl+Enter)
  3. Place cursor after the newlines (or before subsequent text)
  4. Press Backspace repeatedly
  5. Observe that newlines are not removed
  6. Submit the message — the agent receives the newlines intact

Concrete reproduction (tested via agent relay)

  • User typed 77 + 3× \+Enter + 88 → value is 77\n\n\n88
  • User moved cursor before 88 and pressed Backspace many times
  • Submitted message still contained all 3 \n characters

Expected Behavior

Backspace deletes the character before the cursor, including \n characters, just like any other character.

Actual Behavior

Backspace has no effect when the character to be deleted is a \n. The newline remains in the value and is included in the submitted message.

Root Cause Analysis

The data model logic in ui-tui/src/components/textInput.tsx backspace handler (lines 837-857) appears correct on static analysis:

  • canFastBackspace (line 452) returns false when current.includes('\n'), forcing the slow path
  • The slow path uses prevPos()Intl.Segmenter grapheme segmentation, which handles \n correctly (verified via Node.js REPL)
  • String slice deletion and commit() call should produce the correct result

However, empirical testing proves the bug exists. The most likely cause is that the mechanism by which \+Enter (or terminal-specific LF vs CR handling) inserts newlines bypasses the standard commit() flow, leaving internal state (vRef/curRef/lineWidthRef) out of sync with React state. When Backspace then runs against this desynchronized state, the operation appears to succeed at the component level but the parent/composer never sees the change.

Alternatively, the \+Enter hotkey is documented in ui-tui/src/content/hotkeys.ts line 34 ('\\\\+Enter', multi-line continuation fallback) but has no corresponding implementation anywhere in the codebase — the Enter handler (lines 763-773) only checks modifier keys (Shift/Ctrl/Cmd/Meta), not the input content preceding Enter.

Related Issues

Environment

  • OS: Linux (WSL2, 6.6.87.2-microsoft-standard-WSL2, x86_64)
  • Hermes version: v0.12.0 (2026.4.30)
  • Python: 3.11.15
  • Terminal: WSL2 via Windows Terminal

Affected Component

  • TUI (Terminal UI — ui-tui/src/components/textInput.tsx)

Debug Report

N/A — hermes debug share not available from this WSL environment. The bug is reproducible entirely within the TUI composer input and does not involve agent interaction, gateway, or tools.

Metadata

Metadata

Assignees

No one assigned

    Labels

    P2Medium — degraded but workaround existscomp/tuiTerminal UI (ui-tui/ + tui_gateway/)type/bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions