{"record":{"id":"19c6c1a7d4c7c46b","repo":"github/github-mcp-server","slug":"perpage-value-d-exceeds-maximum-of-100","errorCode":null,"errorMessage":"perPage value %d exceeds maximum of 100","messagePattern":"perPage value (.+?) exceeds maximum of 100","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"pkg/github/params.go","lineNumber":477,"sourceCode":"\tHasNextPage     bool   `json:\"hasNextPage\"`\n\tHasPreviousPage bool   `json:\"hasPreviousPage\"`\n\tNextCursor      string `json:\"nextCursor,omitempty\"`\n\tPrevCursor      string `json:\"prevCursor,omitempty\"`\n}\n\nfunc buildPageInfo(resp *github.Response) pageInfo {\n\treturn pageInfo{\n\t\tHasNextPage:     resp.After != \"\",\n\t\tHasPreviousPage: resp.Before != \"\",\n\t\tNextCursor:      resp.After,\n\t\tPrevCursor:      resp.Before,\n\t}\n}\n\n// ToGraphQLParams converts cursor pagination parameters to GraphQL-specific parameters.\nfunc (p CursorPaginationParams) ToGraphQLParams() (*GraphQLPaginationParams, error) {\n\tif p.PerPage > 100 {\n\t\treturn nil, fmt.Errorf(\"perPage value %d exceeds maximum of 100\", p.PerPage)\n\t}\n\tif p.PerPage < 0 {\n\t\treturn nil, fmt.Errorf(\"perPage value %d cannot be negative\", p.PerPage)\n\t}\n\tfirst := int32(p.PerPage)\n\n\tvar after *string\n\tif p.After != \"\" {\n\t\tafter = &p.After\n\t}\n\n\treturn &GraphQLPaginationParams{\n\t\tFirst: &first,\n\t\tAfter: after,\n\t}, nil\n}\n\ntype GraphQLPaginationParams struct {","sourceCodeStart":459,"sourceCodeEnd":495,"githubUrl":"https://github.com/github/github-mcp-server/blob/0ea1f775a7c73eff1bd2e25904d01136756bbfe2/pkg/github/params.go#L459-L495","documentation":"Returned by CursorPaginationParams.ToGraphQLParams when perPage exceeds 100. GitHub's GraphQL API enforces a hard ceiling of 100 items per page on first/last arguments, and this validation fails fast before a doomed request is sent. The value flows from the per_page tool argument into cursor-based GraphQL pagination (ProjectsV2, etc.).","triggerScenarios":"Calling a GraphQL-backed tool (e.g. list_project_items, search via GraphQL path) with per_page > 100; a client defaulting page size to 200; chaining a REST-tuned pagination config (REST allows up to 100 per page for many endpoints) into a GraphQL-backed tool.","commonSituations":"Porting scripts from REST endpoints where higher limits were accepted; configuration shared across tools where one tool's max differs; teams standardizing on a large page size hitting the first GraphQL-backed tool.","solutions":["Set per_page to 100 or lower for GraphQL-backed tools","Omit per_page entirely and let the server default apply","Make the limit data-driven per tool (REST vs GraphQL) instead of one global constant","If you need more than 100 items, follow pagination cursors (pageInfo.nextCursor/after) across multiple calls"],"exampleFix":"// before\n{\"per_page\":200}\n// after\n{\"per_page\":100}","handlingStrategy":"validation","validationCode":"const maxGraphQLPerPage = 100\nfunc clampPerPage(n int) int {\n    if n > maxGraphQLPerPage {\n        return maxGraphQLPerPage\n    }\n    if n < 0 {\n        return 0\n    }\n    return n\n}\n// before building the call:\nargs[\"per_page\"] = clampPerPage(requestedPerPage)","typeGuard":"func isValidPerPage(n int) bool {\n    return n >= 0 && n <= 100\n}","tryCatchPattern":"gqlParams, err := cursor.ToGraphQLParams()\nif err != nil {\n    if strings.Contains(err.Error(), \"exceeds maximum\") {\n        gqlParams, _ = (&github.CursorPaginationParams{PerPage: 100, After: cursor.After}).ToGraphQLParams()\n    } else {\n        return err\n    }\n}","preventionTips":["Cap page size at 100 for any GitHub-backed call — REST or GraphQL","Paginate with cursors (after/before) instead of inflating page size","Keep per-tool limits in config, not one shared constant across REST and GraphQL tools"],"tags":["go","github-api","graphql","pagination","validation"],"backgroundTag":null,"analyzedSha":"0ea1f775a7c73eff1bd2e25904d01136756bbfe2","analyzedAt":"2026-08-15T18:10:19.804Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}