[BUG] Mods: Client onKey gets a lone space as undocumented "space" and unnamed keys (F1, Insert, F12) as raw escape sequences

Status Open
Reported on v2.1.290
Maintainer reply None cached
Activity 0 comments · opened Oct 13, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (both cases come from the same key-to-ClientKeyEvent mapping)
  • [x] Observed on 2.1.290; I checked the 2.1.296 build and the mapping is the same (see Version)

What's Wrong?

The ClientKeyEvent.key docs say it is "A special key's name (up, down, left, right, return, tab, backspace, delete, pageup, home, ...) or the character typed". Two kinds of key break that contract.

  1. A space typed on its own arrives as key: "space". That name isn't in the docs. When the space arrives in the same input chunk as other text, it is a literal " " instead. Fast typing and IME commits ("녕 ") both do this. So a Client text editor that inserts non-special keys as text writes the word space some of the time, depending on typing speed and input method.
  2. Keys that have no name arrive as their raw escape sequence. F1 arrives as key: "\^[OP", Insert as "\^[[2~", F12 as "\^[[24~". If a Client draws that text, the drawing is refused and the Client goes down. After that, every keystroke goes to the prompt. In my session, the Shift+Tab that followed switched the permission mode.

The mapping in the bundle appears to name a lone " " as space and, for a key with no single-code-point input, to fall back to sequence.

What Should Happen?

  • A lone space should arrive the same way as a space inside a chunk (" "). Failing that, space, and every other name the engine can produce, should be listed in ClientKeyEvent's docs.
  • Unnamed keys should get a name (f1 to f12, insert, ...) or not be delivered at all. They should never arrive as raw escape sequences posing as "the character typed".

Error Messages/Logs

<plugin>: Client hooks/editor.tsx: returned a tree that does not validate (a text child holds a control character (an escape sequence))

Steps to Reproduce

  1. Make a mod with a Pane whose tree holds a Client with this module:

``js
export default (props, surface) => {
const { Text } = surface.elements
if (surface.state === undefined) {
surface.setState('')
surface.onKey(k => surface.setState(surface.state + JSON.stringify(k.key) + ' '))
}
return Text({ children: surface.state || 'click here and type' })
}
``

  1. Start Claude Code with the fullscreen renderer, open the pane and click the Client.
  2. Press Space on its own. The Client shows "space". In tmux, send-keys -l "a b" shows "a b".
  3. Press F1. The Client shows "\^[OP".
  4. Change the module to insert k.key without JSON.stringify and press F1 again. The Client is replaced by the error above, and the next keys go to the prompt.

Claude Model

Not relevant (Haiku 4.5 in the test session)

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.290 (Claude Code). The 2.1.296 darwin-arm64 build has the same mapping.

Platform

Other (Claude Team subscription)

Operating System

macOS 27.0.1

Terminal/Shell

tmux 3.6a, and Orca 1.4.220 (xterm.js)

View original on GitHub ↗