Forgejo API curls lack --connect-timeout: a brief git.sherver.org blip wedges a tick ~30s and false-trips the healthcheck #395
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
Due date
No due date set.
Dependencies
No dependencies set
Reference
joshtronic/igor#395
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 healthchecks.io task-fail alert paged the operator ~2026-07-15 23:47. The harness was actually healthy — it self-recovered on the very next tick — but the page was real: one tick failed with
status=28.Diagnosis
git.sherver.org had a brief (~few-second) blip. During it, a Forgejo API
curlin the early cascade hung until its--max-time 30expired → curl exit 28 (timeout). Under the tick'sset -euo pipefailthat aborted the tick (rc=28); thecleanup()EXIT trap sawHC_TASK_STARTED=1+ nonzero rc and firedhc_ping task fail(tick.sh ~170) → the check flipped down → alert. The next tick succeeded and re-pinged success (~2 min later) → auto-recovered.Rare — 2 failed ticks in 5 days (this exit-28 + an unrelated exit-3). But a few-second server blip should not wedge a tick ~30s or page the operator.
Root cause
lib/forgejo.sh's curl wrappers use--max-time 30(and60for uploads) with no--connect-timeout. A briefly-unreachable server stalls a call for the full max-time before failing, instead of failing fast (or riding through a sub-second blip). Call volume is not the issue: validation git-fetches are cached 15 min/repo (VALIDATION_COOLDOWN_SECS=900), and a tick makes only ~10-30 small API calls.Fix (this PR)
Add
--connect-timeout 5and tighten--max-time30 → 15 across the Forgejo curl paths (_fj,_forgejo_post_reviewers; the image upload keeps--max-time 60but gains the connect-timeout). A blip now fails (or rides through) in ~5s instead of ~30s — keeps the agent moving. Values hardcoded (one operator). Test shimscurland asserts_fjpasses the fail-fast flags.Follow-up (noted, not in this PR)
Even with fast timeouts, an unguarded best-effort caller (e.g. the recovery sweep's
forgejo_comment/forgejo_unassign_all) still propagates a transient failure fatally, so a blip can still page the operator — just faster. Worth making those idempotent recovery calls best-effort (log + continue) so a transient blip doesn't page at all. The co-locatedbasenamereaper bug (#392) rides this same path — fixed in PR #393.