Where does the bug appear (feature/product)?
Cursor IDE
Describe the Bug
When an application in the integrated terminal enables bracketed paste (DECSET 2004, ESC[?2004h), pasting text that (a) contains multi-byte UTF-8 characters (e.g. Chinese) and (b) exceeds the PTY buffer (~1022 bytes on macOS) delivers only the first chunk: ESC[200~ plus ~1022 bytes, then nothing. The remaining bytes and the closing ESC[201~ are never sent, so the TUI waits for the paste terminator forever. The whole terminal appears frozen and the window has to be force-closed.
Root cause: Cursor bundles [email protected]. In lib/unixTerminal.js (~L215-218), the partial-write requeue uses the byte count returned by fs.write against a JS string (UTF-16 code units):
fs.write(this._fd, data, function (err, written) {
// Requeue any partial writes
if (written < data.length) {
_this._writeQueue.unshift(data.slice(written));
For pure ASCII, bytes == string length, so the requeue is accidentally correct — a 7,000-line English paste works fine. For CJK (3 bytes per character), a typical first write of ~1022 bytes already exceeds the string length in code units, so written < data.length is false: the requeue is skipped entirely and the rest of the paste frame — including ESC[201~ — is silently dropped. (When the string is long enough that requeue does run, data.slice(written) still slices by the wrong unit and can drop middle chunks while the frame still closes.) Short CJK pastes that fit in a single write are unaffected, which is why the bug looks length-dependent.
This bug was introduced upstream by microsoft/node-pty#831 (which added the partial-write requeue) and fixed by Fix string slicing for fs.write by lhecker · Pull Request #835 · microsoft/node-pty · GitHub (merged Dec 2025), which wraps input as Buffer before writing. The fix shipped in node-pty 1.1.0 stable; Cursor 3.16.17 still ships 1.1.0-beta42.
Controls, same clipboard, same TUI:
- Terminal.app (raw + bracketed paste): complete frame, ESC[201~ present — OK
- VS Code integrated terminal: OK
- Cursor, cooked mode (no bracketed paste): works via the paste-confirmation dialog
- Cursor, bracketed paste: broken as described. Note TERM_PROGRAM=vscode, so applications cannot even detect Cursor to work around it.
Fix: bump the bundled node-pty to 1.1.0 stable.
Steps to Reproduce
- Copy a CJK string longer than ~1 KiB, e.g.:
python3 -c “print(‘你好’ * 200)” | pbcopy # ~1.2 KB of Chinese - In Cursor’s integrated terminal, start any program that enables bracketed paste — e.g. a TUI such as the Cursor CLI, or a minimal probe that emits ESC[?2004h and reads stdin.
- Paste.
Observed: the app receives ESC[200~ + ~1022 bytes, then nothing — no remaining content, no ESC[201~. The TUI is stuck in paste mode permanently; the terminal must be force-closed.
Control: the exact same clipboard pastes fine in Terminal.app and VS Code. Pure-ASCII pastes of any length (tested with 7,000 lines) also work in Cursor, because the faulty offset math only diverges for multi-byte characters.
Expected Behavior
The full pasted content is delivered as a complete bracketed-paste frame (ESC[200~ … ESC[201~), regardless of script or length — as Terminal.app and VS Code both do.
Operating System
MacOS
Version Information
Version: 3.16.17 (Universal)
VS Code Extension API: 1.128.0
Commit: 6b2afae0257df2bb5e1835f15165dc2f0de056b0
Date: 2026-08-14T01:41:12.803Z
Layout: Agent Window
Build Type: Stable
Release Track: Default
Electron: 40.10.3
Chromium: 144.0.7559.236
Node.js: 24.15.0
V8: 14.4.258.32-electron.0
xterm.js: 6.1.0-beta.291
OS: Darwin arm64 27.0.0
Additional Information
Raw PTY probe (app with bracketed paste enabled, identical clipboard):
- Cursor: sawStart=true, sawEnd=false; first packet 1022 bytes, then nothing — bracketPasteIncomplete=true
- Terminal.app: sawStart=true, sawEnd=true; full ~1143 bytes — OK
Platform scope: confirmed on macOS. The faulty code is in node-pty’s Unix path (lib/unixTerminal.js), so Linux should be affected identically; Windows uses a different backend and is likely unaffected — but the bundled version is the same everywhere, and the fix is the same dependency bump.
Severity is worse than “hang”: with mostly-ASCII text containing some CJK, each partial write slices at a wrong offset, so middle chunks can be silently dropped while the frame still closes — silent corruption of pasted content, not just freezes.
Happy to attach the probe script and full logs if useful.
Does this stop you from using Cursor
Sometimes - I can sometimes use Cursor