iOS: composer "Paste Image" does nothing — no attachment, no error
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
On iOS, the composer's **Paste Image** action does nothing. Tapping the caret in the message input shows the menu with "Paste Image" (so clipboard detection works), but tapping it neither attaches the screenshot nor shows an error. The first invocation showed iOS's "Allow Paste" consent alert, which was allowed; after that, no prompt and no visible effect at all.
Uploading the same screenshot through the **+** button works, so upload, encoding, and the attachment queue are fine — only the clipboard path is broken.
## Steps to reproduce
1. Take a screenshot on iPhone and copy it to the clipboard.
2. Open a channel in Buzz, tap the composer text field, tap the caret to open the edit menu.
3. Tap **Paste Image**.
Expected: the image is queued as a pending attachment (same result as picking it via **+**).
Actual: nothing happens. No attachment, no error text.
## Environment
- iOS, App Store build **0.10.0** (released 2026-08-13).
- Code path unchanged in `main` @ `93114c9c` and in `mobile-v0.12.0-rc.1`, so this is not fixed by an newer RC.
## Code path
- Menu item and handler: `mobile/lib/features/channels/compose_bar/compose_bar_widget.dart:663-715`
- `pasteClipboardImage` (`:663`) → `MediaUploadService.readClipboardImage()`
- inserted into the iOS **system** menu as a custom item (`:686-696`, `IOSSystemContextMenuItemCustom`) when `SystemContextMenu.isSupportedByField(...)`, otherwise into the Flutter-drawn menu (`:700-710`)
- `mobile/lib/shared/relay/media_upload.dart:312-317` → platform channel `readClipboardImage`
- `mobile/ios/Runner/AppDelegate.swift:319-346`
- `clipboardHasImage` → `UIPasteboard.general.hasImages`
- `readClipboardImage` → `UIPasteboard.general.data(forPasteboardType:)` / `.image`
## Two candidate mechanisms
Both are consistent with the report; they are distinguishable by whether any error text appears.
1. **The custom item's `onPressed` never fires.** The item is added to the OS-rendered menu (`IOSSystemContextMenuItemCustom`, `:690-693`). If the callback is not dispatched back to Dart, the result is exactly "nothing happens" — silent, because no Dart code runs at all.
2. **The pasteboard read returns nothing, and iOS's consent gate is asymmetric with the detection API.** `hasImages` (`AppDelegate.swift:319`) is a no-consent API, so the menu item shows regardless of whether the app may actually read the data. `data(forPasteboardType:)` (`:333`) is gated by the "Allow Paste" alert. A programmatic read from a custom menu item is not the UIKit-mediated paste that carries an implicit grant, so it can return `nil`. In that case `readClipboardImage` yields `null` and `compose_bar_widget.dart:673` sets `uploadError = 'Unable to read pasted image'`, which renders at `compose_bar/layout.dart:80`.
Mechanism 2 should produce visible error text; the reporter saw none, which points at 1 — but this has not been confirmed on device yet. I will add a confirmation as a comment.
## Notes
- Related but different: #5226 (composer long-press menu flickers; PR #4780 addresses that), #6059 (desktop Cmd+V paste), #4592 (Linux paste freezes). None of them cover the iOS custom menu item being inert.
- The keyboard-inserted-content path (`onContentInserted` → `uploadPastedImage`, `compose_bar_widget.dart:717-729`) is a separate route and is not implicated here.
Contributor guide
Research direction
Reproduce on an iOS device, then trace pasteClipboardImage in mobile/lib/features/channels/compose_bar/compose_bar_widget.dart:663-715 through MediaUploadService.readClipboardImage and AppDelegate.swift:319-346. Check whether the IOSSystemContextMenuItemCustom callback fires and whether the pasteboard read returns data; compare any error rendering in compose_bar/layout.dart:80. Done means Paste Image either queues the image like the + button or visibly reports the read failure.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- flutter, ios, swift
- Domain
- mobile
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 72/100