| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
ui_get backs a synchronous UI picker (label/assignee/etc. dropdowns in the MCP App issue/PR write surfaces). Each handler paginated GitHub API results in an unbounded loop (PerPage 100, looping until NextPage==0 / HasNextPage==false). On very large repos/orgs this fans out into dozens of sequential round-trips, and a single slow page inflates the whole call — production telemetry showed a tail spiking to ~20 minutes. Bound every ui_get pagination loop to uiGetMaxPages (10 pages, ~1000 items) and add an additive "has_more" flag indicating results were truncated. Truncation is acceptable here because the picker pairs it with typeahead, so responsiveness matters more than completeness. Affected methods: labels, assignees, milestones, branches, reviewers (both the collaborators and teams loops). uiGetIssueTypes and issue_fields are single-request and left unchanged. has_more is response-only and backward-compatible: no existing keys are removed or renamed, and the tool input schema is unchanged. HTTP-client timeouts are intentionally a separate follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
This PR bounds pagination in the ui_get tool’s synchronous picker endpoints to cap tail latency on large repos/orgs, and surfaces intentional truncation to the UI via an additive has_more response field.
Changes:
| File | Description |
|---|---|
| pkg/github/ui_tools.go | Caps ui_get pagination loops and emits has_more when results are truncated due to the cap. |
| pkg/github/ui_tools_test.go | Adds/extends tests to validate the page cap behavior and has_more semantics for bounded and truncated cases. |
Sorry, something went wrong.
ui_get backs a synchronous UI picker (label/assignee/etc. dropdowns in the MCP App issue/PR write surfaces). Each handler paginated GitHub API results in an unbounded loop (PerPage 100, looping until NextPage==0 / HasNextPage==false). On very large repos/orgs this fans out into dozens of sequential round-trips, and a single slow page inflates the whole call — production telemetry showed a tail spiking to ~20 minutes. Bound every ui_get pagination loop to uiGetMaxPages (10 pages, ~1000 items) and add an additive "has_more" flag indicating results were truncated. Truncation is acceptable here because the picker pairs it with typeahead, so responsiveness matters more than completeness. Affected methods: labels, assignees, milestones, branches, reviewers (both the collaborators and teams loops). uiGetIssueTypes and issue_fields are single-request and left unchanged. has_more is response-only and backward-compatible: no existing keys are removed or renamed, and the tool input schema is unchanged. HTTP-client timeouts are intentionally a separate follow-up. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Sam Morrow <info@sam-morrow.com>
| Back | FazBrowse Home | New Git URL |
Problem
ui_get backs a synchronous UI picker — the label/assignee/milestone/branch/reviewer dropdowns in the MCP App issue/PR write surfaces. Each handler paginated GitHub API results in an unbounded loop (PerPage: 100, looping until NextPage == 0 / HasNextPage == false).
On very large repos/orgs this fans out into dozens of sequential API round-trips, and a single slow/stalled page inflates the whole call. Production telemetry showed ui_get p50 at sub-second but the tail spiking to ~20 minutes (max/p99 ~1.17M–1.29M ms).
Fix
Bound every ui_get pagination loop to a shared package-level constant uiGetMaxPages = 10 (≈1000 items at PerPage 100) and add an additive has_more boolean to each response indicating results were deliberately truncated. The tool is now fast-or-bounded instead of unbounded.
Truncation is an accepted product behavior here: the picker pairs it with typeahead, so responsiveness matters more than completeness.
has_more is computed as "there were more pages we deliberately did not fetch":
Affected methods
uiGetIssueTypes and issue_fields are single-request (no loop) and intentionally left unchanged.