Transient curl timeout in the PR-review pickup path aborts the whole tick (status=28) #425
Labels
No labels
Agent
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/Security
Kind/Testing
Priority
Critical
Priority
High
Priority
Low
Priority
Medium
Reviewed
Confirmed
Reviewed
Duplicate
Reviewed
Invalid
Reviewed
Won't Fix
Status
Abandoned
Status
Blocked
Status
Need More Info
No milestone
No assignees
1 participant
Notifications
Total time spent: 14 minutes 16 seconds
Due date
igor
14 minutes 16 seconds
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#425
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Symptom
A tick dies with
status=28/n/a(curl "operation timed out"), thecleanup()EXIT trap fireshc_ping task fail, and healthchecks.io sends a "DOWN (received a failure signal)" page. The next tick runs clean and the check self-recovers ~2 min later. Cost is one lost tick plus a page — often overnight.Occurrences
Two on 2026-07-25, against zero exit-28 aborts in the preceding six days (the only other exit-code failure in 7 days is an unrelated
status=3on 07-21):Where it actually dies
Both aborts land 8-11s after the
[agent] recovery sweep ($BOT_USER)log line and before[agent] maintenance:. That log line is misleading as an attribution:recovery: ...line, soORPHAN_COUNTwas 0 and the sweep loop never executed.ORPHANS=$(forgejo_my_assigned || echo '[]')— so a curl failure there cannot abort the tick.That puts the failing call downstream of the sweep, in the PR-review pickup block (
bin/tick.sh~3227+), where_fjcallers are unguarded and a non-zero curl exit propagates fatally underset -e.Timeouts are
FORGEJO_CONNECT_TIMEOUT=5/FORGEJO_MAX_TIME=15(lib/forgejo.sh:21-22). Death at 8-11s is consistent with a request that connected and then stalled, not with a connect failure.Ruled out
IPv6 is not the cause here.
git.sherver.orgresolves to both2600:3c03::2000:4fff:fe34:6f12and45.33.72.135; the v6 path refuses fast rather than blackholing, so happy-eyeballs falls through to v4 cleanly:This is distinct from the earlier ssh/git IPv6 blackhole, which is already pinned via
AddressFamily inet.Fixed looks like
A single transient stall costs a retry, not a tick and a page.
_fjrequests (GET/HEAD) — e.g.--retry 2 --retry-delay 1plus retry-on-timeout — so one stalled read is absorbed.forgejo_comment, assign/unassign, merge, and review submissions can succeed server-side and still time out client-side; a naive retry double-posts. Those either stay single-shot or need an explicit "did it land?" re-check before a second attempt._fjcallers in the pickup path: decide per call whether failure should be fatal or best-effort. A read that only decides whether there is review work to pick up should not be able to kill the tick.Tests
_fjGET retries on a simulated timeout and succeeds on the retry._fjGET gives up after the bound and returns non-zero rather than retrying forever.igor referenced this issue2026-07-26 02:15:47 +00:00