Description
When client-side media processing scales an image (because it exceeds the big_image_size_threshold), the -scaled suffix is incorrectly propagated to every sub-size filename instead of being applied only to the scaled image itself. This does not match WordPress core's filename convention.
What it looks like (buggy)
IMG_2300-scaled-1-150x150.jpg
IMG_2300-scaled-1-300x169.jpg
IMG_2300-scaled-1-500x500.jpg
IMG_2300-scaled-1-768x432.jpg
IMG_2300-scaled-1-1024x576.jpg
IMG_2300-scaled-1-1536x864.jpg
IMG_2300-scaled-1-1568x882.jpg
IMG_2300-scaled-1-2048x1152.jpg
IMG_2300-scaled-1-scaled.jpg
IMG_2300-scaled-1.jpg
What it should look like
IMG_2300-150x150.jpg
IMG_2300-300x169.jpg
IMG_2300-500x500.jpg
IMG_2300-768x432.jpg
IMG_2300-1024x576.jpg
IMG_2300-1536x864.jpg
IMG_2300-1568x882.jpg
IMG_2300-2048x1152.jpg
IMG_2300-scaled.jpg
IMG_2300.jpg
This is the naming convention WordPress core uses when wp_create_image_subsizes() scales an image down: only the scaled-down full-size copy carries -scaled, while sub-sizes are derived from the original (un-suffixed) basename, and the unmodified original is preserved alongside it.
Steps to reproduce
- Upload an image larger than
big_image_size_threshold (default 2560px), e.g. a 4000×3000 JPEG.
- Inspect the resulting files in the uploads directory.
Expected: the files named per the second list above.
Actual: the files named per the first list above (every sub-size carries -scaled, plus a redundant -scaled-scaled file).
Scope
Only images that get the scaled-image treatment (larger than the threshold) are affected. Smaller images uploaded with client-side media processing are named correctly.
Root cause
In packages/upload-media/src/store/private-actions.ts, prepareItem() queues a ResizeCrop operation with isThresholdResize: true before Upload. That means the main upload is already a -scaled file — so attachment.filename returned by the server contains -scaled. generateThumbnails() then derives every thumbnail name from attachment.filename, and additionally re-runs the scaled-sideload code path, producing a redundant -scaled-scaled file.
The fix is to upload the original first and rely on the existing scaled-sideload code path (which already exists in generateThumbnails()) to produce the single -scaled file. This matches the HEIC code path and WordPress core's wp_create_image_subsizes() flow, which preserves the original alongside the scaled copy.
Description
When client-side media processing scales an image (because it exceeds the
big_image_size_threshold), the-scaledsuffix is incorrectly propagated to every sub-size filename instead of being applied only to the scaled image itself. This does not match WordPress core's filename convention.What it looks like (buggy)
What it should look like
This is the naming convention WordPress core uses when
wp_create_image_subsizes()scales an image down: only the scaled-down full-size copy carries-scaled, while sub-sizes are derived from the original (un-suffixed) basename, and the unmodified original is preserved alongside it.Steps to reproduce
big_image_size_threshold(default 2560px), e.g. a 4000×3000 JPEG.Expected: the files named per the second list above.
Actual: the files named per the first list above (every sub-size carries
-scaled, plus a redundant-scaled-scaledfile).Scope
Only images that get the scaled-image treatment (larger than the threshold) are affected. Smaller images uploaded with client-side media processing are named correctly.
Root cause
In
packages/upload-media/src/store/private-actions.ts,prepareItem()queues aResizeCropoperation withisThresholdResize: truebeforeUpload. That means the main upload is already a-scaledfile — soattachment.filenamereturned by the server contains-scaled.generateThumbnails()then derives every thumbnail name fromattachment.filename, and additionally re-runs the scaled-sideload code path, producing a redundant-scaled-scaledfile.The fix is to upload the original first and rely on the existing scaled-sideload code path (which already exists in
generateThumbnails()) to produce the single-scaledfile. This matches the HEIC code path and WordPress core'swp_create_image_subsizes()flow, which preserves the original alongside the scaled copy.