MoonshotAI / MoonshotAI/kimi-code

WSL (WSLg): pasting an image does nothing — wl-paste selects undecodable image/bmp and short-circuits the PowerShell fallback

Open
#1,961 0 comments 0 reactions 0 assignees View on GitHub

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-V reaches 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

  1. Drop the "any image/*" fallback in selectPreferredImageMimeType() (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;
  2. Don't pass the temp path through an env var: embed it (single-quote escaped) in the script text, or add the variable to WSLENV in the spawn env, so no user-side configuration is required.

Workaround (for other affected users)

  • Append to WSLENV in your shell startup: WSLENV="$WSLENV:KIMI_WSL_CLIPBOARD_IMAGE_PATH/w";
  • Shim wl-paste earlier in PATH for 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.