You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Upload Media: Endless sideload loop when the browser can't decode a JPEG that wasm-vips can #83512
Uploading a JPEG that wasm-vips can decode but the browser can't sends client-side media processing into an endless loop. The upload never finishes, and the same sub-sizes are sideloaded over and over (-103, -104, ... suffixes) until the tab is closed. In testing it restarted 33 times in 15 seconds, and the server got bogged down enough that new logins timed out.
The cause is in generateThumbnails. After the sub-size children are queued, the big-image threshold check calls createImageBitmap( thumbnailSource ) without a try/catch:
wasm-vips decodes the damaged JPEG tolerantly, so the sub-sizes are generated fine, but createImageBitmap() rejects with "The source image could not be decoded." The thunk throws, finishOperation( id ) never runs, and the parent item stays on THUMBNAIL_GENERATION. Each child's upload completion then calls processItem( parentId ), which starts THUMBNAIL_GENERATION again and queues every sub-size again.
A likely fix is to guard the threshold check so a decode failure skips the -scaled version and still reaches finishOperation. The dimensions could also come from the attachment's reported width and height instead of decoding the file a second time.
Step-by-step reproduction instructions
Make a partly damaged JPEG: take the first 6 KB of a real photo (a 2400x1600 one was used here) and append random bytes: head -c 6000 photo.jpg > damaged.jpg && head -c 20000 /dev/urandom >> damaged.jpg
In Chrome 137+ with client-side media processing enabled, add an Image block and upload damaged.jpg.
With SCRIPT_DEBUG on, the console shows Starting operation THUMBNAIL_GENERATION repeating, along with an uncaught "The source image could not be decoded." each time. The Network tab shows /wp/v2/media/<id>/sideload requests that never stop.
Expected: the upload finishes (with or without a -scaled size), or fails with an error.
Screenshots, screen recording, code snippet
Recorded in the Media Library grid using WordPress/wordpress-develop#12585, which runs the same bundled package. The overlay at the bottom right logs the upload requests:
I found this while recording demos for WordPress/wordpress-develop#12585, and it reproduces the same way in the block editor.
Claude traced the loop back to its source:
AI Use
Investigated and drafted with 🤖 Claude Code.