Skip to content

Bug: Image paste from clipboard broken on Windows (Bun spawn strips $ in PowerShell) #17616

@shaofengluo-ctrl

Description

@shaofengluo-ctrl

Description

Image pasting from clipboard does not work on Windows (CMD or PowerShell terminals). The root cause is in pkg/client/image.go — the PowerShell command used to read clipboard image data contains $ characters that get silently stripped by Bun's spawn on Windows.

Root Cause Analysis

The clipboard reading path calls PowerShell with an inline script like:

powershell -Command "Add-Type -Assembly System.Windows.Forms; $img = [System.Windows.Forms.Clipboard]::GetImage(); ..."

When Bun (the JS runtime bundled in OpenCode) spawns this process on Windows, it passes the command through its own argument processing which strips all $ characters from the command string. This turns $img into img, $ms into ms, etc., producing invalid PowerShell that silently fails.

Evidence

  1. Tested with a minimal reproduction: Bun.spawn(["powershell", "-Command", "echo $env:USERNAME"]) returns empty output on Windows, while cmd /c echo %USERNAME% works fine.
  2. The same PowerShell command works perfectly when executed directly in a terminal.
  3. Workaround confirmed: Changing from inline -Command "..." to -File script.ps1 (where the script is a separate .ps1 file) bypasses the issue entirely, since Bun never sees the $ characters.

Environment

  • OS: Windows Server 2022 / Windows 11
  • Terminal: CMD, PowerShell, Windows Terminal
  • OpenCode Version: v0.1.25 through v1.2.25
  • Runtime: Bun (bundled)

Suggested Fix

Replace the inline PowerShell command with a -File based invocation. Either:

  1. Ship a .ps1 helper script alongside the binary and invoke it via powershell -File clipboard.ps1
  2. Write a temp .ps1 file at runtime, execute it, then clean up
  3. Use -EncodedCommand with a Base64-encoded script block (avoids all escaping issues)

Option 3 is probably cleanest — no temp files, no shipped scripts, and immune to any shell escaping:

script := `Add-Type -Assembly System.Windows.Forms; $img = [System.Windows.Forms.Clipboard]::GetImage(); ...`
encoded := base64.StdEncoding.EncodeToString(utf16le(script))
exec.Command("powershell", "-EncodedCommand", encoded)

Current Workaround

Binary-patch the compiled opencode.exe to replace the inline -Command invocation with a -File call pointing to an external .ps1 script. This survives until the next update.

Related

Metadata

Metadata

Assignees

Labels

coreAnything pertaining to core functionality of the application (opencode server stuff)windows

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions