get_run_logs / get_job_logs always 404 on private repos #25

Open
opened 2026-09-19 14:14:57 +00:00 by Phil · 1 comment
Owner

Symptom

get_run_logs and get_job_logs return logs 404 for every private repo, even when the run exists. Example: flow.raven run_number 27531, DB id 41915, api-tests.yml, job agent-tools, status failure. On 2026-09-19, all 7 log fetches since 12:30 UTC failed identically, in flow.raven, flow.raven-deployment and RavenBot.

Root cause (not a Forgejo outage, not log storage)

  • Forgejo answers in 2–5 ms from the repo access check, before any log lookup: router: completed GET /Philflow/flow.raven/actions/runs/27531/jobs/0/attempt/1/logs ... 404 Not Found in 3.2ms @ context/repo.go:456(context.RepoAssignment).
  • Forgejo 15.0.5 does not evaluate API tokens on web routes. services/auth/method/basic.go:43 reads if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) { return &auth.AuthenticationNotAttempted{} }, and oauth2.go:222 has the same guard. The token sent by DoRaw is ignored, so the request counts as anonymous. For a private repo, anonymous access means 404. This was confirmed in-cluster: anonymous GET /Philflow/flow.raven and /api/v1/repos/Philflow/flow.raven both return 404.
  • Forgejo 15.0.5 has no API endpoint for job logs. routers/api/v1/api.go:888-893 exposes only /actions/tasks, /actions/runs and /actions/runs/{run_id}.
  • diagnoseLogs404 then tells the caller to retry with the run_number. That sends agents in circles, because the run_number was already correct.

The web-route approach came in with 3c2b705 ("drop fictitious /api/v1 paths, use Forgejo web routes"). It can only work for public repos.

To decide

  • A: read logs where Forgejo writes them. This needs a small, token-authenticated log endpoint next to Forgejo, or read access to the actions log storage. Real logs, but an extra component.
  • B: add a job-log API to Forgejo upstream. It is the one clean contract, but a release cycle away.

Until one of them lands, the tool should say plainly that logs are not reachable for private repos instead of blaming the id.

Refs Philflow/auto-issue-orchestrator#215

## Symptom `get_run_logs` and `get_job_logs` return `logs 404` for every private repo, even when the run exists. Example: flow.raven run_number 27531, DB id 41915, api-tests.yml, job agent-tools, status failure. On 2026-09-19, all 7 log fetches since 12:30 UTC failed identically, in flow.raven, flow.raven-deployment and RavenBot. ## Root cause (not a Forgejo outage, not log storage) - Forgejo answers in 2–5 ms from the repo access check, before any log lookup: `router: completed GET /Philflow/flow.raven/actions/runs/27531/jobs/0/attempt/1/logs ... 404 Not Found in 3.2ms @ context/repo.go:456(context.RepoAssignment)`. - Forgejo 15.0.5 does not evaluate API tokens on web routes. `services/auth/method/basic.go:43` reads `if !middleware.IsAPIPath(req) && !isContainerPath(req) && !isAttachmentDownload(req) && !isGitRawOrAttachOrLFSPath(req) { return &auth.AuthenticationNotAttempted{} }`, and `oauth2.go:222` has the same guard. The token sent by `DoRaw` is ignored, so the request counts as anonymous. For a private repo, anonymous access means 404. This was confirmed in-cluster: anonymous `GET /Philflow/flow.raven` and `/api/v1/repos/Philflow/flow.raven` both return 404. - Forgejo 15.0.5 has no API endpoint for job logs. `routers/api/v1/api.go:888-893` exposes only `/actions/tasks`, `/actions/runs` and `/actions/runs/{run_id}`. - `diagnoseLogs404` then tells the caller to retry with the run_number. That sends agents in circles, because the run_number was already correct. The web-route approach came in with 3c2b705 ("drop fictitious /api/v1 paths, use Forgejo web routes"). It can only work for public repos. ## To decide - **A**: read logs where Forgejo writes them. This needs a small, token-authenticated log endpoint next to Forgejo, or read access to the actions log storage. Real logs, but an extra component. - **B**: add a job-log API to Forgejo upstream. It is the one clean contract, but a release cycle away. Until one of them lands, the tool should say plainly that logs are not reachable for private repos instead of blaming the id. Refs Philflow/auto-issue-orchestrator#215
Author
Owner

Workaround finding (2026-09-19): A browser session that is already logged in can read the job logs. In the logged-in browser, fetch('/Philflow/flow.raven/actions/runs/<run_number>/jobs/<job_index>/attempt/1/logs') returns 200 with the full log (29,517 lines for run 27582). The session cookie authenticates the web route; an API token does not (see the analysis above).

This confirms the diagnosis: the route and the log storage work, and only token-based authentication on the web route is missing. It is not a clean fix for agents, because it depends on a human's browser session. The decision between a separate log access and an upstream API is still open.

**Workaround finding (2026-09-19):** A browser session that is already logged in can read the job logs. In the logged-in browser, `fetch('/Philflow/flow.raven/actions/runs/<run_number>/jobs/<job_index>/attempt/1/logs')` returns 200 with the full log (29,517 lines for run 27582). The session cookie authenticates the web route; an API token does not (see the analysis above). This confirms the diagnosis: the route and the log storage work, and only token-based authentication on the web route is missing. It is not a clean fix for agents, because it depends on a human's browser session. The decision between a separate log access and an upstream API is still open.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Phil/forgejo-mcp#25
No description provided.