Skip to content

[Bug]: macOS: Cmd+V with an image on the clipboard inserts nothing in a Claude Code terminal (no orca-paste temp file created) #26739

Closed

Description

@ryotatera

Operating system

macOS

Orca version

1.4.223

Details

Summary

On macOS, pressing Cmd+V in a Claude Code agent terminal with an image on the clipboard inserts nothing. Orca never saves the image to a temp file: no orca-paste-*.png is created in the app temp directory. The same clipboard pastes fine into other apps.

Environment

  • Orca 1.4.223, macOS 26.6 (arm64), shell /bin/zsh
  • Agent: Claude Code 2.1.295, launched by Orca in the worktree's first terminal
  • Screenshot tool: CleanShot X (macOS built-in screenshots not tested yet)

Steps to reproduce

  1. Take a screenshot with CleanShot X so the image is on the clipboard.
  2. Focus a Claude Code agent terminal in Orca.
  3. Press Cmd+V.

Expected

Orca saves the clipboard image to a temp file and pastes its path, and Claude Code attaches the image.

Actual

  • Nothing is inserted into the Claude Code prompt.
  • No orca-paste-*.png file is created under the app temp directory (checked with find /private/var/folders -name 'orca-paste-*.png'; zero results, ever).
  • Nothing related to paste or clipboard appears in logs/main.trace.ndjson.

What I checked

  • After the CleanShot capture, osascript -e 'clipboard info' shows «class furl» (a reference to CleanShot's saved file) plus image types («class PNGf», JPEG, TIFF, ...). There is no text type, and pbpaste returns an empty string.
  • I suspected the furl entry, so I replaced the clipboard with the image only: osascript -e 'set the clipboard to (the clipboard as «class PNGf»)'. After that, clipboard info lists only image types. Cmd+V in Orca still inserts nothing.
  • The image data that CleanShot labels «class PNGf» is actually JPEG (file reports JPEG image data). This might matter if clipboard.readImage() returns an empty image for it, but I haven't confirmed that.

Workaround

A small script saves the clipboard image with osascript (the clipboard as «class PNGf»), converts it with sips -s format png, and gives the file path to the agent.

Possibly related: #18594 (macOS "Paste cancelled").

Activity

  1. ryotatera commented on Oct 9, 2026

    @ryotatera
    Author

    Update: I narrowed it down to the clipboard content CleanShot X produces.

    • A macOS built-in screenshot (Cmd+Ctrl+Shift+4, CleanShot X not running) pastes correctly with Cmd+V. Orca creates orca-paste-*.png and Claude Code attaches the image.
    • With CleanShot X, the data under «class PNGf» is actually JPEG bytes (file reports JPEG image data). Cmd+V fails silently even after removing the «class furl» entry from the clipboard.

    So the trigger looks like JPEG bytes advertised as PNG on the pasteboard. I suspect clipboard.readImage() returns an empty image for that data, and clipboard:saveImageAsTempFile then returns null without any feedback. Two suggestions:

    1. When readImage() is empty, fall back to reading the raw public.png / public.jpeg / public.tiff buffers, or the file behind public.file-url.
    2. Show the "Image paste failed" toast in this case instead of failing silently.
  2. ggbdpq commented on Oct 9, 2026

    @ggbdpq
    Contributor

    @/tmp/orca-26739-issue-comment.md

  3. AmethystLiang commented on Oct 9, 2026

    @AmethystLiang
    Contributor

    Thanks for reporting. Looking into it

  4. flukelaster commented on Oct 10, 2026

    @flukelaster

    Same issue here on macOS with CleanShot X, Orca v1.4.224. One extra data point: on my machine the «class PNGf» data is real PNG, not JPEG, and Cmd+V still inserts nothing. So mislabeled JPEG bytes may not be the only trigger.

    Clipboard contents (copied from CleanShot X)

    • osascript -e 'clipboard info' → «class furl», «class PNGf», «class AVIF», «class 8BPS», GIF, «class jp2 », JPEG, TIFF, «class BMP », «class TPIC»
    • file on the dumped «class PNGf» bytes → PNG image data, 730 x 898, 8-bit/color RGBA
    • The file behind «class furl» is also a real PNG
    • pbpaste returns an empty string (no text flavor)

    Behavior

    • Cmd+V in a Claude Code terminal pane: no orca-paste-*.png is created in $TMPDIR and nothing is inserted
    • Ctrl+V works, because Claude Code reads the clipboard itself
    • The same clipboard pastes fine with Cmd+V in other terminals outside Orca

    Possible regression timing
    main.trace.ndjson has terminal_webgl_diagnostic breadcrumbs with reason: "image-paste" (the image-path paste succeeded) many times up to 2026-10-09 06:51 UTC. After Orca auto-updated to 1.4.224 on 2026-10-09 21:10 UTC, there are none.

  5. ggbdpq commented on Oct 11, 2026

    @ggbdpq
    Contributor

    Two new data points make clear this splits into two layers on v1.4.224:

    1. Gate layer (the v1.4.224 regression). Since #26538, readClipboardImageSource() requires an advertised image/* format. When CleanShot also puts a public.file-url on the pasteboard, Chromium's availableFormats() reports only text/uri-list (per the analysis in #27346), so the paste path bails before clipboard:saveImageAsTempFile is ever invoked. That is consistent with @flukelaster's observation that no orca-paste-*.png is created and the image-paste breadcrumbs stop right after the 1.4.224 auto-update. #27346 fixes exactly this layer.

    2. Decode layer (the originally reported case). Once the gate lets the paste through, clipboard.readImage() still returns an empty image for the mislabeled JPEG-bytes-under-public.png flavor from the original report, so #27346 alone would still end in null there.

    Our #26898 covers that second layer: when readImage() comes back empty on macOS, it reads the raw image/png / image/jpeg / image/tiff buffers and decodes via nativeImage, throwing loudly if nothing decodes. The two fixes compose: #27346 restores reaching the handler, #26898 recovers the bytes readImage() cannot decode.

    Happy to rebase or re-scope #26898 however maintainers prefer, or close it in favor if an upstream fix will cover both layers.

  6. peterkimpmp commented on Oct 11, 2026

    @peterkimpmp

    Another data point on v1.4.224, macOS 26.6.2 (build 25G83), Electron 43.7.5, Claude Code 2.1.296, CleanShot X.

    Timeline from local evidence

    • orca-paste-*.png temp files exist up to 2026-10-10 09:31 (local time, UTC+9). None have been created since.
    • Orca was restarted 2026-10-10 22:38 local. After that restart, Cmd+V with an image never reaches clipboard:saveImageAsTempFile: no orca-paste-*.png is created anywhere under <tmp> or the app user-data folder.
    • The main trace log records updater.install 1.4.224 at 2026-10-10 22:38:32 local, i.e. the regression starts exactly when 1.4.224 was installed (the earlier working process was 1.4.223).

    Image-only clipboard also fails on my machine

    • I replaced the clipboard with real PNG data only: osascript -e 'set the clipboard to (read (POSIX file "<png>") as «class PNGf»)'.
    • After that, clipboard info listed only image flavors (PNGf, AVIF, 8BPS, GIF, jp2, JPEG, TIFF, BMP, TPIC). There was no «class furl» and no text.
    • Cmd+V in the Claude Code pane still inserted nothing, and no temp file was created.
    • If fix(clipboard): paste a macOS image copied beside its file URL #27346 only handles the "image beside a file URL" case, this image-only case may need a separate check.

    Keybindings and workaround

    • terminal.paste uses the default (Mod+V), with no user override in the profile state.
    • Ctrl+V works: Claude Code reads the clipboard image itself.

    Hypothesis, unverified

    • While reading the bundled renderer code, I saw a darwin keydown branch that skips terminal.paste handling when metaKey && key === "v". That press then falls through to the native paste event, which reads text/plain only.
    • If this is the active desktop path, Cmd+V would never reach j9 (the text-first, then image-temp-file paste routine) for an image-only clipboard.
    • I may be looking at the web-client bundle rather than the desktop one.

    Happy to test a build that includes #27346.

  7. marunrun commented on Oct 16, 2026

    @marunrun

    Root cause pinned + reproducible probe — the merged fix in #27346 does not fire on real CleanShot data

    I reproduced this end-to-end on v1.4.227 (Electron 43.7.5, so it includes the #27346 fallback) with a CleanShot X capture: window.api.ui.clipboardHasImage() → false, window.api.ui.saveClipboardImageAsTempFile() → null, Cmd+V inserts nothing. Same clipboard pastes fine via Claude Code's own Ctrl+V (osascript).

    What the probe shows (minimal Electron app, reading the pasteboard only):

    pasteboard shape has('public.png') 43.7.5 / 43.7.8 readImage()
    standard UTI write (native screenshot) true / true non-empty
    furl + legacy PNGf carrying real PNG bytes true / false non-empty
    furl + legacy PNGf carrying JPEG bytes + TIFF/JPEG/GIF/BMP (≈ real CleanShot) false / false non-empty
    legacy PNGf only false / false empty

    Two consequences:

    1. fix(clipboard): paste a macOS image copied beside its file URL #27346's verification shape (PNGf with real PNG bytes + file URL) hits the has() bridging and works, but real CleanShot data (JPEG bytes inside PNGf, extra flavors) does not — clipboard.has('public.png') returns false on 43.7.5, so the darwin fallback never fires. This matches the reporter's observation that CleanShot's PNGf payload is actually JPEG.
    2. On the same pasteboard where has() is false, clipboard.readImage() returns non-empty pixels (when a file URL is present alongside). So a last-resort "darwin: if source detection found nothing, accept a non-empty readImage()" in readClipboardImageSource (src/main/window/clipboard-image-source.ts) would recover the paste. Only the flavor-only PNGf-with-no-URL shape stays broken, where readImage() is genuinely empty.

    Also a correction to the regression timeline above: 1.4.223 already failed (this issue was filed against it), so this is not a 1.4.224 regression — real CleanShot pasteboards never matched #27346's tested shape.

    Probe (agent-runnable, deterministic): a Swift writer that declares public.file-url + PNGf(JPEG bytes)+TIFF+JPEG+GIF+BMP, then an Electron reader printing availableFormats / has() / readImage().isEmpty(). Happy to attach the scripts if useful.

    Probe scripts (deterministic, no window shown)

    cleanshot-full-write.swift — writes the CleanShot-shape pasteboard:

    import AppKit
    
    let dir = "/tmp/clipboard-probe"
    func read(_ name: String) -> Data? {
      FileManager.default.contents(atPath: "\(dir)/\(name)")
    }
    guard let jpeg = read("fixture.jpg"), let png = read("fixture.png"),
          let tiff = read("fixture.tiff"), let gif = read("fixture.gif"),
          let bmp = read("fixture.bmp") else {
      print("writer: fixture read failed"); exit(1)
    }
    
    let pb = NSPasteboard.general
    pb.clearContents()
    let types: [NSPasteboard.PasteboardType] = [
      .fileURL,                              // «class furl»
      NSPasteboard.PasteboardType("PNGf"),   // legacy PNG flavor (JPEG bytes inside)
      NSPasteboard.PasteboardType("TIFF"),
      NSPasteboard.PasteboardType("JPEG"),
      NSPasteboard.PasteboardType("GIF"),
      NSPasteboard.PasteboardType("BMP")
    ]
    pb.declareTypes(types, owner: nil)
    pb.setData(NSURL(fileURLWithPath: "\(dir)/fixture.png").dataRepresentation, forType: .fileURL)
    pb.setData(jpeg, forType: NSPasteboard.PasteboardType("PNGf"))
    pb.setData(tiff, forType: NSPasteboard.PasteboardType("TIFF"))
    pb.setData(jpeg, forType: NSPasteboard.PasteboardType("JPEG"))
    pb.setData(gif, forType: NSPasteboard.PasteboardType("GIF"))
    pb.setData(bmp, forType: NSPasteboard.PasteboardType("BMP"))
    print("writer: types now =", pb.types?.map(\.rawValue) ?? [])

    reader.js — Electron reader probe:

    const { app, clipboard } = require('electron')
    app.whenReady().then(() => {
      const safe = (fn) => {
        try {
          return fn()
        } catch (e) {
          return 'THROW: ' + e.message
        }
      }
      const out = {
        electron: process.versions.electron,
        availableFormats: clipboard.availableFormats(),
        has_public_png: safe(() => clipboard.has('public.png')),
        has_public_tiff: safe(() => clipboard.has('public.tiff')),
        readImage_isEmpty: clipboard.readImage().isEmpty(),
        readText: clipboard.readText(),
        readBuffer_PNGf_len: safe(() => clipboard.readBuffer('PNGf').length)
      }
      console.log('PROBE ' + JSON.stringify(out))
      app.quit()
    })

    Run: swift cleanshot-full-write.swift && electron reader.js with Electron 43.7.5 and 43.7.8. Result on both: availableFormats has no image/*, has('public.png') false, readImage() non-empty (with the file URL present).

  8. nwparker commented on Oct 16, 2026

    @nwparker
    Contributor

    Thanks, we're prioitizing this

  9. self-assigned this
    on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

os:macosIssues affecting macOS

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions