An asset-browsing app I maintain lets you drag an image card straight out of the browser and onto the desktop. At some point that stopped working, and “it used to work” is one of the least useful bug reports there is — it names a symptom and a feeling of certainty, and nothing about a cause.

Finding the moment it broke

Grepping through the project's history turned up the exact commit: a change from a few days earlier had disabled the native drag behaviour on the image element, with a comment saying the surrounding container would take over the job. The container-level implementation the comment promised had never actually been written. The user's memory of “it used to work” was correct — dragging had worked by default, on the plain image tag, until that one line quietly took it away and nothing replaced it.

Rebuilding it, and still failing

I rebuilt the drag behaviour at the container level: on drag start, populate the browser's data-transfer object with a file download reference for desktop drops, a raw file object for a web-to-web drop, and a text fallback underneath both. Since a drag-start handler is synchronous and the image data lives on a server, the file has to be pre-fetched before the user ever picks the card up, triggered on hover or press so it's ready by the time the drag begins.

It still didn't work for dragging onto another web page. So I built a small diagnostic page: the real app in one frame, a drop zone and a set of copy/paste probes in another, and — the part that mattered — a control tile holding a file that had nothing to do with the app at all, pre-loaded and just sitting there.

The control tile changed the question

The control tile failed exactly the same way the app did. At the moment the drag started, the payload correctly listed one file. By the time it landed on the other page, the payload had been reduced to plain text and an internal drag identifier — the file itself was gone. Since the control tile shared nothing with the app's code, the app could not be the thing at fault.

Chrome does not support dragging a file from one web page to another. A file built in memory from fetched data, of the kind both the app and the control tile were using, apparently never serializes into a browser-to-browser drag payload in the first place. What had looked like a regression to hunt down in application code was a browser limitation that a differential test with a deliberately unrelated control was the only way to see clearly — without it, every retry would have looked like more evidence that the app's own code was still wrong somewhere.

What shipped instead

Dragging to the desktop still works, and now exports the full-resolution original under its real filename instead of a 600px thumbnail, since dragging to a browser tab was never going to be salvageable and dragging to the desktop was the only path left worth optimizing. Copying to the clipboard shipped as a separate, explicit action — button, keyboard shortcut, and a fallback path with a plain-language explanation for the one case that still fails: the page has to be served over a secure connection for the clipboard API to be available at all, and it says so when it isn't.