labctl pr logs: Forgejo log adapter 500s on retried runs (attempt/2), blocking lander validation #259
Labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Cloonar/coding-lab#259
Loading…
Add table
Add a link
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?
Hit while validating #258 (branch
afk/257) as an autoland lander.labctl pr logscould not return any logs, so the failing-check triage step of the validation core was impossible through the CLI.Symptom
Both forms fail identically:
What is actually going on
The adapter resolves the latest attempt and requests
…/attempt/2/logs. On these runs that route genuinely 500s on the forge side — butattempt/1serves fine:So this is not purely a shape/version mismatch — the forge has no stored log blob for attempt 2 (these runs were retried during a forge outage; see below), and the adapter treats the 500 as terminal instead of falling back.
Suggested fixes
--attempt <n>so an operator can reach a specific attempt directly.Why it matters
The validation core tells a lander to read failing jobs' logs before any local repro. With this broken, a lander on a container without the project toolchain (no
nix/go/node) has no path to triage a red check at all, and has to fall back tocurl-ing the forge web routes by hand — which is what I did here.Context
The #258 runs this surfaced on were themselves infra casualties: both attempt-1 logs stop ~75s in with no error recorded, ~10 minutes before the jobs were marked "Failing after 11m42s", and the forge was returning
connection refusedthen502 Bad Gatewayduring the same window.Agent Brief
Category: bug
Summary: The Forgejo log adapter treats a forge-side 5xx on the latest attempt as a terminal "adapter mismatch", instead of falling back to an earlier attempt's logs and reporting upstream errors honestly.
Current behavior:
Tracker.CheckLogon the Forgejo backend resolves a check's Actions job from its commit-statustarget_urland probesattempt/1, 2, …until the first 404, serving the last 200 (the ADR-0060 design). Any other answer — including an upstream 500 — falls into a catch-all that wrapstracker.ErrLogAdapterMismatch, whose message claims "lab's Forgejo log adapter does not match this forge version; file an issue on coding-lab". The agentapi PR-logs handler maps that to a 502, andlabctl pr logsprints it for both the default (failing subset) and--checkforms.Repro confirmed by code trace and the reporter's HTTP evidence: on runs retried during a forge outage, the forge stores no log blob for attempt 2 and 500s on its log route, while attempt 1 serves 200 with full logs. The adapter dies on the attempt-2 500 and never serves the attempt-1 logs it could have. The misleading "forge version" framing sent the reporter hunting a version incompatibility when the real cause was a missing log blob. An existing adapter fixture test deliberately pins the 500→mismatch fold, so this is designed-then-outgrown behavior, not an accident.
Desired behavior:
200 text/plain, serve the newest attempt's logs that did answer 200. The fallback must be loud per ADR-0060's "loud, never silent" pin: the operator runninglabctl pr logsmust be told which attempt's logs they are reading and that the latest attempt's logs were unavailable (upstream status included), without corrupting the log body on stdout as a parse/pipe surface.ErrLogAdapterMismatchremains reserved for genuine shape surprises: a 200 that isn'ttext/plain, a 404 on attempt 1, atarget_urlthat stops matching the Actions job shape, the attempt-probe cap.Key interfaces:
CheckLogattempt-probe loop — its status handling needs the fallback and the new error classification.tracker.ErrLogAdapterMismatch— unchanged in meaning, narrowed in application. A sibling sentinel (or equivalent distinguishable error) for "forge log route upstream error" is expected.labctl pr logsstderr messaging — whatever mechanism carries the "served attempt N, latest attempt M errored" notice must reach the CLI user (stderr), not silently vanish server-side.Acceptance criteria:
labctl pr logs(both default and--checkforms) exits 0, prints the earlier attempt's logs, and announces the fallback (attempt served, latest-attempt upstream status) out of band of the log body.text/plain200, 404 on attempt 1, unmatchedtarget_urlshape, probe cap exceeded) still produceErrLogAdapterMismatchwith the existing actionable message.Out of scope:
--attempt <n>operator flag (the reporter's suggestion 3) — file separately if wanted; the fallback covers the operational need that motivated it.