Skip to content

id(web): pasting or dropping only oversized images silently swallows the paste — event claimed, nothing inserted, no feedback #1321

Closed

Description

@dezren39

Bug

In the id web editor, pasting (or dropping) images where every image exceeds MAX_IMAGE_SIZE (10 MB) silently does nothing: the paste/drop is claimed by the image-upload plugin, the browser default is prevented, and no content of any kind is inserted. The only feedback is a console.warn, which users never see.

Evidence

pkgs/id/web/src/image-upload.ts:

  • handlePaste (~L185-202): filters clipboardData.files to image files; if any image file exists it calls event.preventDefault() and returns true — before the size check. In the loop, oversized files are skipped with continue after a console.warn (~L193-196). If all image files are oversized, the handler has already claimed the paste and inserts nothing.
  • handleDrop (~L204-228) has the identical shape: preventDefault() + claim first, size filter inside the loop.

Verified this run on main 1bf2afb2 with a targeted vitest probe against the real plugin props (probe since removed):

  • Single oversized PNG (MAX_IMAGE_SIZE + 1 bytes): handlePaste returned true, preventDefault called once, view.dispatch called 0 times — nothing uploaded, nothing inserted, paste swallowed.
  • Control (text file only, no image): returned false, no preventDefault — normal paste proceeds.

Because the event is claimed, any other clipboard content in the same paste (e.g. text/HTML copied alongside an image from a web page) is also lost, not just the image.

Why it matters

A user pasting a large screenshot or photo (camera photos and retina screenshots routinely exceed 10 MB) gets a completely silent no-op in a collaborative editor — indistinguishable from the app hanging or the paste being lost. This is the same class of silent-failure defect as the txt save data-loss issues (#1306/#1307): the app claims an action and drops user content without a word.

Acceptance criteria

  • When no pasted/dropped file will actually be uploaded (all images oversized), the handler does not claim the event: it returns false without preventDefault(), so ProseMirror's default paste/drop handling (text/HTML content, if any) still runs.
  • When at least one image is accepted, oversized siblings are still skipped, and the rejection is surfaced to the user in the UI (not only console.warn) — e.g. a visible notice naming the file and the 10 MB limit. (If the notice mechanism needs a design choice, the un-claiming fix alone satisfies the data-loss half; file the notice as a follow-up.)
  • Regression tests in pkgs/id/web/src/image-upload.test.ts driving handlePaste/handleDrop with stub views/events: oversized-only paste returns false and never dispatches; mixed valid+oversized paste uploads only the valid file; oversized-only drop behaves the same as paste.
  • Existing web tests still pass (cd pkgs/id/web && bun run test / vitest).

Activity

  1. developing-today commented on Oct 27, 2026

    @developing-today
    Contributor
  2. added
    kind/bugSomething isn't working (prefixed form of the classic bug label)
    queue/queuedHas a queued task in the Supabase agent queue
    source/creatorFiled by the new-issue-creator job
    task/small-fixQueue packet kind: bounded fix with reproduction and targeted tests
    priority/normalOrdinary priority (the default)
    app/idPackage/app: id (pkgs/ or apps/ in this repo)
    effort/sSmall: expected under 2 hours of work
    on Oct 27, 2026
  3. dezren39 commented on Oct 27, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · state: filed

    • Agent: new-issue-creator job
    • Session / ID: new-issue-creator run, 2026-10-27T06:47Z
    • Found via: filed this run
    • Task: Filed after verifying on main 1bf2afb with a targeted vitest probe against the real image-upload plugin props: a single oversized PNG (MAX_IMAGE_SIZE+1) makes handlePaste return true + preventDefault with 0 dispatches — the paste is claimed and silently swallowed (image-upload.ts handlePaste/handleDrop claim the event before the in-loop size skip; control text-only paste returns false).
    • Expectation: effort s — small fix: don't claim the event when no file will be uploaded (return false, no preventDefault), keep skipping oversized siblings when at least one file is accepted, add handler-level regression tests in image-upload.test.ts.
    • Links: body: hidden_files/issue-code-image-upload-oversized-paste-body.md; queue packet packet-1321.json (repo-health-code-pilot)
  4. added
    work/assignedQueue worker lifecycle state
    queue/claimedQueue worker lifecycle state
    and removed
    queue/queuedHas a queued task in the Supabase agent queue
    on Oct 28, 2026
  5. 119 remaining items

  6. added
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    status/parkedDeliberately paused with a recorded resume condition
    and removed
    queue/claimedQueue worker lifecycle state
    on Oct 28, 2026
  7. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · parked

    • Agent: queue worker (repo-worker-code), Lane A shift
    • Session / ID: queue task 1311
    • Found via: queue claim (resume)
    • Task: Re-parked — PR 1576 @cbbb829c at 27 pass / 0 fail (test-web-unit green), but test-web-typecheck, web-fmt-check and two crash-gate flake jobs were still pending after a 5-minute poll.
    • Expectation: Resume in ~20 min: merge PR 1576 when the remaining checks complete green, then complete fixed_merged.
    • Links: PR fix(id): do not claim paste/drop when every image is oversized (#1321) #1576
  8. added
    queue/claimedQueue worker lifecycle state
    and removed
    status/parkedDeliberately paused with a recorded resume condition
    queue/parkedQueue task is parked (waiting on CI, time, or an event)
    on Oct 28, 2026
  9. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · picked up

  10. dezren39 commented on Oct 28, 2026

    @dezren39
    MemberAuthor

    🤖 Agent note · done

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

app/idPackage/app: id (pkgs/ or apps/ in this repo)effort/sSmall: expected under 2 hours of workkind/bugSomething isn't working (prefixed form of the classic bug label)priority/normalOrdinary priority (the default)source/creatorFiled by the new-issue-creator jobtask/small-fixQueue packet kind: bounded fix with reproduction and targeted tests

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions