[BUG] Ctrl+J / LF newline is hardcoded in the chat input, so unbinding ctrl+j in keybindings.json has no effect (breaks SKK IMEs)

Status Open
Reported on v2.1.278
Maintainer reply None cached
Activity 0 comments · opened Sep 22, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report
  • [x] I am using the latest version of Claude Code

What's Wrong?

Unbinding ctrl+j in ~/.claude/keybindings.json has no effect: pressing Ctrl+J in the chat input still inserts a newline.

{
  "$schema": "https://www.schemastore.org/claude-code-keybindings.json",
  "bindings": [
    { "context": "Chat", "bindings": { "ctrl+j": null } }
  ]
}

The cause is visible in the bundled input code (v2.1.278). The text input component handles the raw LF key / Ctrl+J directly, before and independently of the keybinding layer, so removing the chat:newline binding does not stop it:

if(W&&(N.name==="enter"||N.ctrl&&!N.shift&&!N.meta&&N.name==="j")){
  N.preventDefault();let re=pe.insert("\n");te(re.text),Z(re.offset);return
}

(N.name==="enter" is the parser's name for a raw \n byte; \r is "return".)

Why this matters: SKK-family Japanese IMEs (macSKK, AquaSKK, ddskk) use Ctrl+J as their primary key for confirming a conversion and for switching to hiragana mode. In terminals such as Terminal.app and iTerm2, Ctrl+J is delivered to the pty as LF (0x0A) as well as being seen by the IME, so every SKK confirmation inserts a stray newline into the prompt. The documented way to opt out ("ctrl+j": null) does not work because of the hardcoded path above.

Related: #17649 (AquaSKK, closed with a Karabiner workaround) describes the IME side; this report is specifically that the keybinding override is not honored.

What Should Happen?

When ctrl+j is unbound (or chat:newline is rebound to a different key) in keybindings.json, a Ctrl+J / LF keypress in the chat input should not insert a newline. Newline insertion should go through the chat:newline action only, so that user bindings are respected.

Error Messages/Logs

$ claude --version
2.1.278 (Claude Code)

No error is printed. keybindings.json loads without validation warnings.

Steps to Reproduce

  1. Create ~/.claude/keybindings.json with the content above (unbind ctrl+j in the Chat context).
  2. Start claude in Terminal.app (or iTerm2) on macOS. No IME is required to reproduce.
  3. Type some text in the prompt, then press Ctrl+J.
  4. A newline is inserted, even though ctrl+j is unbound. Rebinding chat:newline to another key (e.g. ctrl+x ctrl+j) also leaves Ctrl+J inserting a newline.

Environment

  • Claude Code 2.1.278 (native install, ~/.local/share/claude/versions/2.1.278)
  • macOS 26 (Darwin 25.5.0), Terminal.app, zsh
  • IME: macSKK 2.19.0 (the trigger for noticing this, but not needed to reproduce)

View original on GitHub ↗