Skip to content

New media uploads are offloaded while Image Storage rollback is active #1159

Description

@pirate-bot

Status (2026-10-11)

Fixed in PR #1174 (bugfix/1159 → development, approved by pirate-bot at aed92868).

  • Fix: while an Image Storage rollback runs, new uploads stay in the media library. The hook that offloads a new upload, and the filename deduplication that goes with it, are now registered only while Image Storage is on. Offloaded images keep being served from Optimole during the rollback, as before.
  • Tests: with a rollback in progress, neither hook is registered and a new upload keeps a local file. The test fails on development.
  • To know: an upload made during a rollback keeps its local file; a not-yet-restored image with the same name in the same month folder is then restored with a -1 suffix.
  • Not proven: on a live connected site (the local test site is not connected to Optimole).

Summary

Images added to the WordPress Media Library while an Image Storage rollback is active can still be transferred to Optimole Cloud. Starting rollback is expected to stop cloud offloading for new uploads while existing cloud images are restored locally. Instead, newly added media can continue entering the offload workflow, preventing users from reliably stopping additional cloud transfers during recovery.

Customer context

  • Product / area: Optimole Pro, Image Storage rollback and media uploads
  • Version: Unknown from the ticket; defect is present in inspected tag v4.2.14
  • Environment: WordPress; other environment details not provided
  • Integration / third party: WordPress attachment metadata generation
  • Reported error / symptom: Newly added images continue going to Optimole servers while rollback is in progress
  • Impact: Additional media can be cloud-offloaded while the user is attempting to stop offloading and restore local files

Reproduction notes

Code-backed reproduction:

  1. Enable Optimole Image Storage offloading and offload at least one image.
  2. Start Rollback so rollback_status becomes enabled and offload_media becomes disabled.
  3. While rollback remains active, upload a new image to the WordPress Media Library.
  4. Observe that the new attachment still enters Optimole’s metadata-generation/offload callback and can be transferred to cloud storage.

The source path is confirmed in v4.2.14; a controlled WordPress runtime reproduction was not performed.

Diagnosis

Conclusion

The plugin disables the offload_media setting when rollback starts, but treats any active rollback as equivalent to enabled offloading during bootstrap. This registers the attachment-metadata callback that uploads newly generated media to Optimole Cloud. The callback has no rollback-state guard, so a new image uploaded during rollback can follow the normal offload path. This directly matches the reported continued cloud uploads.

Where this likely occurs

  • assets/src/dashboard/parts/connected/settings/OffloadMedia.js — onRollbackdMedia() lines 138–160 sets rollback_status to enabled and offload_media to disabled before starting rollback.
  • inc/settings.php — Optml_Settings::is_offload_enabled() lines 875–882 returns true when either offloading is enabled or rollback is active.
  • inc/media_offload.php — Optml_Media_Offload::instance() lines 154–185 registers generate_image_meta() on wp_generate_attachment_metadata whenever is_offload_enabled() is true.
  • inc/media_offload.php — Optml_Media_Offload::generate_image_meta() lines 1289–1379 validates and prepares a newly generated attachment for cloud upload without distinguishing rollback from normal offload mode.
  • Git history: commit 723d891d57cf66713ad73cca58ca1e61725743e0 changed rollback to satisfy is_offload_enabled() and first appears in tag v3.11.1; tag containment confirms the behavior remains through v4.2.14. The preceding implementation only registered these hooks when offload_media itself was enabled.

Engineering notes

Rollback requires portions of the media-offload subsystem to remain available for restoring and rendering existing offloaded attachments. The inspected bootstrap gate groups URL handling, attachment rendering, post filtering, and new-upload processing under the same state check. The confirmed scope is new WordPress image attachments created while bulk rollback status is active; other upload mechanisms were not tested.

Test coverage status

tests/test-media.php includes successful rollback coverage in test_image_rollback() lines 348–358 and rollback scheduling/locking coverage at lines 643–741. No relevant coverage was found during inspection for creating a new attachment while rollback_status is enabled and offload_media is disabled.

What to verify or explore next

  • May be worth reproducing on v4.2.14 by starting rollback, uploading one image through the Media Library, and checking its local file, attachment metadata, offload flags, and cloud record.
  • May be worth comparing the same workflow on v3.11.0 and v3.11.1 to verify the identified release boundary at runtime.
  • If reproducible, checking uploads through the block editor, WooCommerce product media, and REST media endpoint could establish whether they share the attachment-metadata path.

Unknowns / follow-up

The customer’s installed plugin version and the exact upload interface are unknown. No runtime logs were provided, and WordPress core source was not inspected in this plugin-only workspace.

Confidence

Confidence: 96/100

Repository inspection confirms that new attachments can enter the cloud-offload path while rollback is active. The separate stalled-restoration report matches open issue #1108, which was read and already contains evidence from the linked parent HelpScout conversation.


Source: HelpScout #3458633804
Generated by bug-report-triage (ID: bug-report-triage_6ab26de1374543.30050428)

Activity

  1. added theissue type on Sep 22, 2026
  2. self-assigned this
    on Oct 9, 2026
  3. milicavs commented on Oct 11, 2026

    @milicavs

    🧪 QA steps and test sandbox

    While Optimole is transferring offloaded images back to the site (Image Storage rollback), images uploaded to the Media Library at the same time are still sent to Optimole Cloud, so a user who is trying to bring everything back keeps getting new images offloaded.

    Requires: your own Optimole account (API key) with Image Storage available.

    Step Build Bot check
    Reproduce the bug Optimole 4.2.16 (released) ⏭️ Not checked: needs an Optimole account
    Verify the fix PR #1174 build aed9286 ⏭️ Not checked: needs an Optimole account (the bot confirmed the build installs over the release)

    On the sandbox:

    • https://qa-optimole-wp-1159.s1-sandywp.com runs the release. Sign in to SandyWP and use the sandbox's Auto Login.
    • The Media Library already has three 1600px images to offload.
    • Tools → QA Logs shows debug.log, which the public site can't read.
    • If it has stopped after a day without use, the next qa-playground run brings it back.

    Reproduce on Optimole 4.2.16:

    1. Optimole → connect with your API key.
    2. Optimole → Settings → Image Storage: turn on offloading and offload the existing images.
    3. In the same screen, start Transfer back from Optimole (rollback).
    4. While the transfer runs, go to Media → Add New Media File and upload a new image.
    5. Open the new image in Media → Library and copy its File URL.
    • Bug: the new image is offloaded: its URL points to Optimole, not to /wp-content/uploads/….
    • Fixed: the new image stays local: its URL is /wp-content/uploads/… and opens.

    Verify the fix on the same sandbox:

    1. Download the PR build above, then go to Plugins → Add New Plugin → Upload Plugin and click Replace current with uploaded.
    2. Repeat the steps above from step 2.
    • Fixed: as above. Plugins still shows 4.2.16, since the build has no version bump.
    Edge cases
    • Image Storage on and no transfer running: a new upload is offloaded as before.
    • During the rollback, already offloaded images still display on the front end until they are restored.
    • Upload during the rollback a file with the same name as an offloaded image from the same month: after the rollback, the restored one gets a -1 suffix and both display.
    • After the rollback finishes, new uploads stay local.

    Fix: #1174 (open)

  4. pirate-bot commented on Oct 11, 2026

    @pirate-bot
    CollaboratorAuthor

    QA agent — 🟢 Passing checks · Rollback uploads stay local; normal offloading and restoration still work in the simulated connected flow.

    On a seeded paid account with mocked Optimole services, new uploads stayed local during rollback and normal uploads still offloaded. Existing cloud attachment URLs and rendering data remained intact. Transfer back restored the older same-name image with a -1 suffix without overwriting the new upload. The base reproduced the bug, while the candidate passed the same journey, the upload boundary matrix, and the older WordPress hook checks.

    Worth a human look

    1. Repeat rollback-time uploads on a live connected Optimole site and confirm existing cloud images still display.
    2. Check cloud-attachment replacement controls on a live connected site; the seeded cloud edit screen logged a single-attachment.js null-listener error outside the tested upload flow.
    Checks (4 passed)
    • ✅ After starting Transfer back from Optimole, a new image uploaded through Media Add New during active rollback keeps a wp-content/uploads URL, local attachment metadata and a file on disk without entering cloud offloading.
    • ✅ An existing not-yet-restored offloaded image retains its Optimole attachment URL and usable attachment rendering data while rollback is active.
    • ✅ With Image Storage enabled and no transfer running, uploading a new image through Media Add New offloads it as before, with cloud metadata and removal of the local original.
    • ✅ The transfer back restores the existing cloud image locally without overwriting a same-name new upload made during rollback; the restored file receives a -1 suffix.

    Full report, evidence and session trail

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

Metadata

Metadata

Assignees

Labels

bug-reportbug-report-triagecustomer reportIndicates the request came from a customer.regressionIssue represents a change in behavior from a previous version that is not intended or desired..

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions