Addendum to the previous report — two further issues in the same module (2.2.2). These affect the manual Image Converter run, not the upload path.
3. auto_convert is a global kill switch, not just an upload-time setting — it silently disables manual conversion.
CM_Image_Converter_Core::should_skip_conversion() (class-image-converter-core.php:715-721) returns true for every image when the setting is off:
if (!$this->get_converter()->get_setting('auto_convert')) {
return true;
}
The same setting is already checked at the three upload entry points (class-image-converter-hooks.php:108, 163, 201), which is where it belongs. Checking it again inside should_skip_conversion() means that with “Auto-Convert on Upload” unchecked, the “Start Image Converter” button converts nothing at all: convert_image() bails at core.php:74 and returns WP_Error('conversion_skipped') for every attachment. No admin notice, no log entry explaining why, and the settings UI gives no hint that the checkbox governs manual runs.
On our site this leaves the operator with no safe option: with the setting off, the batch run does nothing; with it on, every new media upload hits the broken hook from issue 1 above. Manual conversion should be gated on the user’s explicit action, not on the auto-convert preference.
4. process_batch() restarts from the beginning indefinitely when any original can never be converted.
CM_Image_Converter_Progress::process_batch() (class-image-converter-progress.php:114-136): when the ID cursor reaches the end of the range but actionable_original_count > 0, it returns 'complete' => false with 'cursor' => 0 (lines 127-131), so the next batch starts over from ID 0. The JS in assets/js/image-converter.js calls processNextBatch() recursively on every non-complete response (lines 572-575), with no cap in the plain conversion path — the sweep loops forever. In the guided workflow the poll is bounded by maxStatusAttempts = 120 (line 1028), but its exit condition is percentage >= 100 || originalRemaining === 0 (line 1083), which is likewise unreachable, so after ~2 minutes it reports “Status Check Timeout — the conversion may still be running in the background”, which is misleading: nothing is running.
There is no exit for the case where an image simply cannot be converted. On our library this reproduced exactly: 956 WebP, 74 remaining JPEG/PNG, 46 of them already flagged {"reason":"larger_output"}, leaving 28 actionable that never convert because of issue 3. The progress bar sat at “956 of 984 processed (97%)” with all action buttons disabled, cycling through the library indefinitely.
Two contributing details:
get_batch_attachment_ids() (class-image-converter-progress.php:231-255) filters only by MIME type, post_status, the ID cursor and the excluded list. Attachments already carrying _cm_conversion_skipped are re-fetched and re-attempted on every sweep, so each loop redundantly re-encodes the 46 known larger_output files before discarding the result.
ajax_get_conversion_status() reports 'original' => $actionable_original (class-image-converter-ajax.php:174), so the JS originalRemaining === 0 check can only ever be satisfied by full conversion — a permanently unconvertible original keeps both exit conditions false.
Suggested fix: abort the sweep when a full pass converts zero images (track conversions per pass and stop instead of resetting the cursor), report those attachments as “could not convert” rather than looping, and exclude _cm_conversion_skipped attachments from get_batch_attachment_ids() unless a force flag is set.