Repository navigation
fix: stop retrying a failing transfer step forever - #1194
Conversation
When a background transfer step threw (an API error, a lookup that keeps failing), it was rescheduled 10 seconds later with the same step, with no limit. The transfer stayed "in progress" in the dashboard and never finished. The failed attempts of a step are now counted; after 5 in a row the chain moves on to the next step, so the transfer can reach its end and the images left behind can be retried. A successful step clears the count. Refs #1108 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEXWtYdE6e3ALYtqtP8j2p
There was a problem hiding this comment.
🟡 Changes requested
A failing step is now skipped, but the transfer then reports success, and the failure count leaks into later transfers.
Questions for the author
- Can
schedule_action()fail to enqueue the next step after the fifth failure deleted the counter? If so, what restarts the chain?
Validation details
- Files reviewed: 2/2 changed files. The row "Caps and limits: Dropped items" was not settled.
- The new tests pass at HEAD
cd /repo && set -o pipefail; timeout 600 vendor/bin/phpunit --do-not-cache-result --configuration=phpunit.xml --filter '…printedOK (2 tests, 4 assertions)(run R2). - A base tree with only the new constants fails both tests [R4].
- An every-attempt-throws run ended with
show_offload_finish_noticeset torollback[R6].
Untested areas
- Caps and limits: Dropped items. Open
inc/media_offload.php:1585. Check which images a later step selects after a skip. The plugin sets no query order. - Real WP-Cron delivery and dashboard rendering were not run.
🤖 Automated review · run code-review-agent_6ad7d074b3a561.25362889.
🤖 Review agent — review posted ✅ on a2936822 · changes requested · 5 findings · 32 min
Run code-review-agent_6ad7d074b3a561.25362889 · trail
… after skips Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEXWtYdE6e3ALYtqtP8j2p
|
On the review question: if Generated by Claude Code |
There was a problem hiding this comment.
🟡 Changes requested
The earlier correctness and type findings are fixed, but one comment in the finish branch is now false.
Questions for the author
- Five failed attempts per step can mean five tries for each remaining step. What data or support report shows that this limit fits real transfer sizes?
Validation details
- Files reviewed: 2/2 changed files. The rows "Caps and limits: Dropped items" and "Caps and limits: Stable order" were not settled.
- The
Test_Mediaclass passes at HEAD:OK (61 tests, 224 assertions)[R4]. - Three mutants each fail one of the new tests [R5].
- A run where every step throws ends with no success notice [R6].
- The prior run code-review-agent_6ad7d074b3a561.25362889 showed the success notice at
a293682. It was not rerun.
Untested areas
- Caps and limits: Dropped items. Caps and limits: Stable order. Open
inc/media_offload.php:1586. The query sets no order, so check which images a step selects after a skip. - The object cache behavior of the new option was not checked against the installed WordPress code.
- Real WP-Cron delivery and dashboard rendering were not run.
🤖 Automated review · run code-review-agent_6ad7dd9b91b1b9.00424458.
🤖 Review agent — review posted ✅ on 2aa00e47 · changes requested · 1 finding · 22 min
Run code-review-agent_6ad7dd9b91b1b9.00424458 · trail
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MEXWtYdE6e3ALYtqtP8j2p
|
On the retry limit: there's no support data behind 5; it's a judgment call. The batch is retried 10 seconds apart, so 5 attempts gives a transient API or memory error about 50 seconds to clear before the chain moves on, and the worst case for a transfer where every step fails is 5 × the number of batches attempts instead of an endless loop. The constant Generated by Claude Code |
There was a problem hiding this comment.
🟢 Approved
The PR passes. Both open threads are fixed, and the one new commit only corrects a comment.
Validation details
- Files reviewed: 2/2 changed files. The row "Caps and limits: Realistic volume" was not settled.
- Since the prior review, commit
8db9a18changes only the comment atinc/media_offload.php:2298. - The WordPress 7.1.3 option code reads a non-autoloaded option back from the database on a cache miss. A cache eviction cannot reset the failure count.
- A skipped step leaves no marker on images. Later steps and new transfers select those images again.
- Run code-review-agent_6ad7dd9b91b1b9.00424458 at
2aa00e4passedTest_Mediawith 61 tests. Its mutants each failed a new test. Not rerun.
Untested areas
- Caps and limits: Realistic volume. No data shows how long real API outages last. Five attempts cover about 50 seconds per step.
- Real WP-Cron delivery and dashboard rendering were not run.
🤖 Automated review · run code-review-agent_6ad7e4bfc50668.80138776.
🤖 Review agent — review posted ✅ on 8db9a187 · approved · 0 findings · 23 min
Run code-review-agent_6ad7e4bfc50668.80138776 · trail
Requested by Marius · project thread
All Submissions:
Changes proposed in this Pull Request:
Part of #1108, covering the 2026-09-22 report of a transfer that stayed "in progress" for 20+ hours.
When a background transfer step throws (an API error, or a lookup that keeps failing),
start_processing_images()reschedules the same step 10 seconds later with no limit. If the cause doesn't go away, the chain retries that step forever and the dashboard keeps polling an active transfer.Each step's failed attempts are now counted in the non-autoloaded
optml_transfer_step_failuresoption (an option, so an object cache eviction can't reset the count). The record carries the transfer lock token, so failures from an earlier or stopped transfer never count toward a new one, and it is deleted when a transfer starts and when it finishes.MAX_STEP_RETRIES(5) failures in a row, the chain logs it and moves on to the next step, so the transfer can reach its end. A successful step clears the count.Not covered: the other condition in the issue, an action that is scheduled but never executes (WP-Cron or Action Scheduler not running on the site). The plugin can only detect that, not run the work. The current transfer lock already lets
maybe_reschedule()restart the chain once the lock expires.How to test the changes in this Pull Request:
generateurls-prod.i.optimole.com.Other information:
inc/media_offload.phpNot proven: a live stuck transfer. Codex review was skipped because the Codex CLI isn't available in this environment.
Generated by Claude Code