Skip to content

[bug] Infinite API pagination loop when Gitea/Forgejo token cannot see all org repos #1108

@Leeh1984

Description

@Leeh1984

Describe the bug

When using a Gitea/Forgejo connection with "orgs" config, if the API token's user does not have access to all
repositories in the organization, Sourcebot enters an infinite pagination loop. It calls GET
/api/v1/orgs/{org}/repos?limit=100&page=N with N incrementing indefinitely (observed page numbers exceeding 330,000)
at 10+ requests per second, effectively DoS-ing the Forgejo instance.

The Forgejo API reports the org's total repo count in its response, but the token can only see a subset. Sourcebot
appears to keep paginating because the number of collected repos never matches the reported total.

Expected behavior: Sourcebot should stop paginating when the API returns an empty page, regardless of the reported
total count.

To reproduce

  1. Set up a Gitea/Forgejo org with multiple repos (e.g. 13)
  2. Create a user and API token that only has collaborator access to some repos in the org (not org-level member)
  3. Configure Sourcebot with "orgs" pointing to that org:
    {
    "connections": {
    "forgejo": {
    "type": "gitea",
    "url": "https://forgejo.example.com",
    "token": { "env": "GITEA_TOKEN" },
    "orgs": ["MyOrg"]
    }
    }
    }
  4. Start Sourcebot
  5. Observe the Gitea/Forgejo access logs — page numbers will climb into the hundreds of thousands and never stop

Sourcebot deployment information

Sourcebot v4.16.8 (also reproduced on v4.15.11). Self-hosted via Docker Compose against a self-hosted Forgejo (12.0.1+gitea-1.22.0)
instance.

Additional information

Impact is severe — the constant API requests (each taking 600-2000ms) cause Forgejo to become unresponsive with slow
SQL queries (5-9 seconds), 500 errors on the web UI, and degraded service for all users and CI systems. Sourcebot's
own web UI also starts throwing NOT_AUTHENTICATED errors due to the backend being overwhelmed.

Workaround: Give the token's user org-level read access to all repositories (via an org team with "All repositories"
permission) so the visible repo count matches the reported total.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions