[BUG] TUI rendering corrupted in neovim's built-in terminal (macOS)

Status Closed — not planned
Reported on v2.1.17
Maintainer reply None cached
Activity 11 comments · opened Jan 23, 2026 · closed May 3, 2026

Preflight Checklist

  • [x] I have searched existing issues and this hasn't been reported yet
  • [x] This is a single bug report (please file separate reports for different bugs)
  • [x] I am using the latest version of Claude Code

What's Wrong?

When running Claude Code inside neovim's built-in :terminal, permission prompts and other interactive UI elements render with overlapping/duplicated text. Menu options appear multiple times, text fragments get garbled (e.g., >sc tNocancel), and "Tab to add additional instructions" appears twice.

This issue is only observed when running Claude Code inside neovim's terminal - running in a regular terminal (iTerm2, Terminal.app, etc.) works correctly.

What Should Happen?

UI elements should render cleanly without overlapping or duplication.

Error Messages/Logs

No error messages - this is a visual rendering issue.

Steps to Reproduce

  1. Open neovim
  2. Run :terminal to open a terminal buffer
  3. Run claude to start Claude Code
  4. Trigger any permission prompt (e.g., request a file edit)
  5. Observe garbled/overlapping UI elements in the permission prompt

Claude Model

Opus

Is this a regression?

I don't know

Last Working Version

_No response_

Claude Code Version

2.1.17

Platform

Anthropic API

Operating System

macOS

Terminal/Shell

Other

Additional Information

  • Terminal width: 120 columns (issue persists even with wide terminal)
  • $TERM: xterm-256color
  • Neovim version: 0.11.5
  • macOS Darwin 24.6.0

Root Cause Analysis

Neovim's :terminal uses libvterm, which does not appear to support synchronized output (DEC mode 2026). This is the protocol modern TUI applications use to prevent screen tearing by batching screen updates.

  • Neovim's own TUI supports mode 2026 (since v0.10), but this is for neovim rendering to a host terminal
  • Neovim's embedded terminal emulator (:terminal) does not appear to support mode 2026 for applications running inside it
  • When Claude Code's TUI sends synchronized output sequences to a terminal that doesn't support them, the cursor positioning and screen updates don't work correctly, causing overlapping/garbled output

This appears similar to #19637 (Windows cmd rendering corruption) - Windows cmd also lacks modern terminal features.

Suggested fix: Claude Code could detect when synchronized output mode 2026 is not supported (via DECRQM query) and fall back to simpler rendering that doesn't rely on it.

References:

View original on GitHub ↗

11 Comments

mgleonard425 · 7 months ago

Screenshot

<img width="604" height="152" alt="Image" src="https://github.com/user-attachments/assets/4518234e-b983-4621-9df3-010609322444" />

github-actions[bot] · 7 months ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/19533
  2. https://github.com/anthropics/claude-code/issues/17775
  3. https://github.com/anthropics/claude-code/issues/14613

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

mgleonard425 · 7 months ago

This is not a duplicate issue. It's possible that this has the same root cause as #19533, but this issue tracks a different platform

mgleonard425 · 7 months ago

Workaround

Running Claude Code inside tmux within neovim's terminal resolves the rendering issues. tmux properly supports synchronized output (mode 2026) and translates the escape sequences correctly.

Setup

Add to your neovim config (~/.config/nvim/init.lua):

-- Open terminal with tmux (reattach to existing session or create new)
vim.api.nvim_create_user_command('T', function()
  vim.cmd('terminal tmux new-session -A -s main')
end, {})

Then use :T instead of :terminal, and run claude inside the tmux session.

---

Note: This is a workaround, not a fix. The underlying issue (Claude Code not gracefully degrading when mode 2026 is unavailable) still exists and affects users who don't want to use tmux.

hovissimo · 6 months ago

I'm seeing this on macos in plain vim9 (which also uses libvterm).

Hoffs · 5 months ago

@mgleonard425 has the 2026 mode support in neovim fixed this for you? Running nightly still seems to be causing tearing from time to time, could be that claude is doing very frequent batches

mgleonard425 · 5 months ago

@Hoffs patially, not entirely. I think my PR in neovim fixed the worst of the garbling and random ASCII. However, the behavior exhibited in the screenshot I shared earlier still persists. I'm debugging this in my spare time - will update here if I manage to root-cause

mconq-asana · 5 months ago

Hi! I'm seeing similar garbled text as I edit in ghostty, iterm and terminal (all with and without using tmux).

  • v2.1.85, macOS Darwin 25.4.0
  • Affects Ghostty, iTerm, terminal, and tmux (so it's not mode 2026 passthrough)
  • DA1/DCS responses (^[P>|tmux 3.6a^[\^[[?1;2;4c) leak into input on startup
  • Backspace produces ?????, raw escape sequences ([[O, [[127;3u7;3uu, ^[[I) render as text
  • Resizing the window triggers a clean re-render and fixes it temporarily

Some random diagnostic checks:

~/sandbox (next-master) % locale
LANG="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_CTYPE="en_US.UTF-8"
LC_MESSAGES="en_US.UTF-8"
LC_MONETARY="en_US.UTF-8"
LC_NUMERIC="en_US.UTF-8"
LC_TIME="en_US.UTF-8"
LC_ALL=
~/sandbox (next-master) %   echo $LANG $LC_ALL
en_US.UTF-8
~/sandbox (next-master) % echo $ZSH_THEME

~/sandbox next-master) % ich starship 2>/dev/null && echo "starship active"
~/sandbox next-master) % echo $GHOSTTY_SHELL_INTEGRATION_NO_CURSOR

~/sandbox (next-master) % node --version
v25.2.1 (also happens with node 22 for me)

~/sandbox (next-master) % sw_vers
ProductName:            macOS
ProductVersion:         26.4
BuildVersion:           25E246

<img width="1562" height="158" alt="Image" src="https://github.com/user-attachments/assets/117272fb-e9f3-4d58-bc60-b5a028d6aba0" />

mconq-asana · 5 months ago

Replying here in case it helps anyone. I discovered there was another python process that was also attached to stdin which was interfering with Claude Code from getting clean input.

github-actions[bot] · 3 months ago

Closing for now — inactive for too long. Please open a new issue if this is still relevant.

github-actions[bot] · 2 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.