MoonshotAI / MoonshotAI/kimi-code
WSL (WSLg): pasting an image does nothing — wl-paste selects undecodable image/bmp and short-circuits the PowerShell fallback
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 7.5k
- Forks
- 1.2k
- Avg merge
- 11h 53m
- Merged PRs (30d)
- 350
Description
Environment
- kimi-code 0.28.0
- Windows 11 + WSL2 (Ubuntu 24.04), WSLg 1.0.73.2
- Terminal: WezTerm (confirmed
Ctrl-Vreaches the TUI — this is not the terminal-swallowing-the-key issue from #316)
Symptom
With an image in the Windows clipboard (e.g. a Win+Shift+S screenshot), pressing Ctrl-V in the kimi TUI inside WSL does nothing at all: no image placeholder appears, and no text is pasted.
Root cause (two compounding bugs)
1. wl-paste selects image/bmp, which the pipeline can't decode — and it short-circuits the WSL PowerShell fallback
WSLg bridges Windows clipboard images into the Wayland clipboard only as image/bmp (verified: wl-paste --list-types shows just image/bmp; xclip's TARGETS contains no image types at all).
In apps/kimi-code/src/utils/clipboard/clipboard-image.ts, selectPreferredImageMimeType() falls back to accepting any image/* type when none of the SUPPORTED_IMAGE_MIME_TYPES (png/jpeg/webp/gif) match:
const anyImage = normalized.find((t) => t.base.startsWith('image/'));
return anyImage?.raw ?? null;
So readClipboardImageViaWlPaste() successfully returns BMP bytes, image !== null in readClipboardMedia(), and the WSL-specific readClipboardImageViaPowerShell() fallback never runs. The BMP is then rejected by isSupportedImageMimeType() and the whole paste is silently dropped.
I shim-logged the actual subprocess calls kimi makes on Ctrl-V; every keypress produces exactly this sequence:
wl-paste --list-types
xclip -selection clipboard -t TARGETS -o
wl-paste --list-types
wl-paste --type image/bmp --no-newline ← BMP is read, then nothing
wslpath / powershell.exe are never invoked, confirming the chain above.
2. The PowerShell fallback itself is broken on a stock WSL setup: the env var can't cross the WSL boundary
readClipboardImageViaPowerShell() hands over the temp path via an environment variable:
env: { ...process.env, KIMI_WSL_CLIPBOARD_IMAGE_PATH: winPath },
But WSL only forwards environment variables listed in WSLENV to Win32 processes (verified: without it, $env:KIMI_WSL_CLIPBOARD_IMAGE_PATH is empty in PowerShell; with WSLENV=KIMI_WSL_CLIPBOARD_IMAGE_PATH/w it works). Without it, $img.Save($null) throws (non-terminating), the script still prints ok, and the subsequent readFileSync(tmpFile) fails — so the fallback silently returns null.
I reproduced kimi's exact logic manually (wslpath producing a \\wsl.localhost\... UNC path + the same PowerShell command) and, with WSLENV set, the full round-trip succeeds and yields a valid PNG.
Suggested fix
- Drop the "any
image/*" fallback inselectPreferredImageMimeType()(or only fall back to decodable types), so a BMP-only clipboard returns null at the wl-paste stage and the WSL PowerShell fallback actually runs; - Don't pass the temp path through an env var: embed it (single-quote escaped) in the script text, or add the variable to
WSLENVin the spawn env, so no user-side configuration is required.
Workaround (for other affected users)
- Append to
WSLENVin your shell startup:WSLENV="$WSLENV:KIMI_WSL_CLIPBOARD_IMAGE_PATH/w"; - Shim
wl-pasteearlier inPATHfor kimi so that--type image/*reads fail (passing text/uri-list through), forcing the flow onto the PowerShell PNG branch. With both in place, pasting works and shows a proper image placeholder.
A PR with both fixes is on the way.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in apps/kimi-code/src/utils/clipboard/clipboard-image.ts, reading selectPreferredImageMimeType(), readClipboardImageViaWlPaste(), readClipboardImageViaPowerShell(), and readClipboardMedia(). Reproduce the WSLg image clipboard flow, then verify that BMP-only clipboard data reaches the PowerShell PNG path without requiring WSLENV and that Ctrl-V produces an image placeholder.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- linux, powershell, typescript
- Domain
- cli, operating-systems
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 56/100