Where does the bug appear (feature/product)?
Cursor IDE
Describe the Bug
Title: On Windows, Chinese prompt in hooks stdin becomes “???” while execution.log shows correct text
Environment:
- OS: Windows 10/11 (Chinese locale)
- Cursor version: 2.2.29 (also reproduced on 2.2.20)
- Hook type: beforeSubmitPrompt
- Config file: C:\Users<username>.cursor\hooks.json
Issue:
When I type a Chinese prompt in Cursor, for example:
测试一条中文,不用回答
I can see the correct Chinese text in:
Settings → Hooks → execution.log
for the corresponding hook invocation. This suggests Cursor’s internal representation of prompt is correct (proper Unicode/UTF‑8).
However, inside my hook process (reading from stdin), the JSON payload’s prompt field has already turned into a series of question marks. For example:
“prompt”: “???”
I verified this by:
- Writing stdin directly to a file (no extra processing), and
- Later by reading stdin in PowerShell and logging the raw JSON.
In the hex dump of that JSON, the prompt segment looks like:
22 70 72 6F 6D 70 74 22 3A 22 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 3F 22
=> “prompt”:“???”
So at the point the hook process receives data over stdin, all non‑ASCII Chinese characters have already been replaced by ASCII 0x3F (?). There are no remaining UTF‑8 multibyte sequences to recover the original Chinese text.
At the same time, the same hook execution entry in execution.log shows the full correct Chinese prompt, e.g.:
“prompt”: “测试一条中文,不用回答”
This strongly suggests:
- Inside Cursor, the
promptstring is correct (Unicode), - But when writing the JSON payload to the hook child process via stdin on Windows, some encoding layer is using a non‑UTF‑8 code page and replacing unrepresentable characters with
?.
Current hooks.json (example):
{
“version”: 1,
“hooks”: {
“beforeSubmitPrompt”: [
{
“command”: “powershell.exe”,
“args”: [
“-NoProfile”,
“-ExecutionPolicy”,
“Bypass”,
“-File”,
“hooks\record-chat.ps1”
]
}
]
}
}
In record-chat.ps1 I:
- Read all of stdin via
[Console]::OpenStandardInput()/StreamReader(UTF‑8 aware), ConvertFrom-Jsonto parse the payload,- Write
payload.prompttoC:\Users\<username>\.cursor\chat_history.txtusing UTF‑8 (no BOM).
But by the time the script runs, payload.prompt is already "????...", so the corruption happens before my hook code.
I also tried a pure batch (.bat) hook that just dumps stdin to a file; the JSON there already has "prompt":"????...", consistent with the above.
Expected behavior:
- The JSON payload written to the hook’s stdin on Windows should preserve the exact same
prompttext as shown inexecution.log, i.e. full Chinese text encoded as UTF‑8, not downgraded to?.
Suspected root cause:
- On Windows, when spawning the hook process and writing to its stdin, Cursor (or a lower‑level library) is encoding the JSON using the system code page (e.g. 936/GBK or 437) instead of UTF‑8, and any characters not representable in that code page are replaced with
?(0x3F). execution.logprints the in‑memory Unicode string directly, so it shows correct Chinese.
Questions / Requests:
- Can you confirm what encoding Cursor uses when sending the hook JSON payload to stdin on Windows?
- Is there any known limitation where a non‑UTF‑8 code page is used for hooks on Windows?
- Could this be changed/fixed so that hooks always receive UTF‑8 JSON on stdin (matching what
execution.logshows), regardless of system code page?
I can provide:
- Full
record-chat.ps1, - The hooks.json used,
- Screenshots of
execution.logwith correct Chinese prompt, - And the raw JSON captured from stdin where
promptis"????...".
Steps to Reproduce
When I type a Chinese prompt in Cursor, for example:
测试一条中文,不用回答
I can see the correct Chinese text in:
Settings → Hooks → execution.log
for the corresponding hook invocation. This suggests Cursor’s internal representation of prompt is correct (proper Unicode/UTF‑8).
However, inside my hook process (reading from stdin), the JSON payload’s prompt field has already turned into a series of question marks. For example:
“prompt”: “???”
I verified this by:
- Writing stdin directly to a file (no extra processing), and
- Later by reading stdin in PowerShell and logging the raw JSON.
Operating System
Windows 10/11
Current Cursor Version (Menu → About Cursor → Copy)
Version: 2.2.29 (user setup)
VSCode Version: 1.105.1
Commit: 656af3704923280dedba3ccd49cfaf9b9d456e90
Date: 2025-12-17T03:49:27.355Z
Electron: 37.7.0
Chromium: 138.0.7204.251
Node.js: 22.20.0
V8: 13.8.258.32-electron.0
OS: Windows_NT x64 10.0.26100
Does this stop you from using Cursor
No - Cursor works, but with this issue