Skip to content

list_dependabot_alerts fails with HTTP 400 since pagination was added (page-based params on a cursor-only API) #2649

@Janosch

Description

@Janosch

Describe the bug

Since #2451 (merged 2026-05-20), list_dependabot_alerts always returns:

400 Pagination using the `page` parameter is not supported

The tool is effectively unusable — any call fails, regardless of arguments, because the handler unconditionally sends page=1.

The GitHub Dependabot alerts REST API (GET /repos/{owner}/{repo}/dependabot/alerts) does not support page-based pagination. It only supports cursor-based pagination (before / after). Sending a page query parameter is rejected with a 400.

Root cause

#2451 wired all three GHAS list tools to the page-based helper OptionalPaginationParams, which defaults page to 1:

// pkg/github/params.go
func OptionalPaginationParams(args map[string]any) (PaginationParams, error) {
    page, err := OptionalIntParamWithDefault(args, "page", 1) // <- always 1 by default
    ...
}

pkg/github/dependabot.go then puts that on the request options unconditionally:

pagination, err := OptionalPaginationParams(args)
...
ListOptions: github.ListOptions{
    Page:    pagination.Page,    // = 1  -> sent as ?page=1 -> 400
    PerPage: pagination.PerPage,
},

So a page query param is sent on every call, which the Dependabot alerts endpoint rejects.

This is correct for list_code_scanning_alerts (that endpoint does support page), which is likely why it slipped through review — only one of the three endpoints in the PR is cursor-only.

The codebase already has the right helper for this case, in the same file:

// pkg/github/params.go
// OptionalCursorPaginationParams returns the "perPage" and "after" parameters,
// without the "page" parameter, suitable for cursor-based pagination only.
func OptionalCursorPaginationParams(args map[string]any) (CursorPaginationParams, error) { ... }

Suggested fix

Switch list_dependabot_alerts from page-based to cursor-based pagination:

  • Use WithCursorPagination(schema) instead of WithPagination(schema) so the tool exposes perPage / after but not page.
  • In the handler, use OptionalCursorPaginationParams(args) and populate only PerPage and After on github.AlertListOptions (do not set Page).

secret_scanning.go should be audited too — the secret scanning alerts API is likewise cursor-based and may have the same regression.

Why tests didn't catch it

dependabot_test.go mocks the GitHub API and happily returns data for page=1, so the real 400 from the live endpoint never surfaces in CI. A test that asserts no page query parameter is sent (or a mock that 400s on page) would have caught it.

Steps to reproduce

  1. Call list_dependabot_alerts with any args, e.g. { "owner": "<org>", "repo": "<repo>", "state": "fixed" }.
  2. Observe: 400 Pagination using the page parameter is not supported.

Workaround

Use the REST API directly, which negotiates cursor pagination correctly:

gh api repos/{owner}/{repo}/dependabot/alerts --paginate -f state=fixed

Affected version

Remote/hosted MCP server, and any build including #2451 (merged 2026-05-20).

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions