Skip to content

feat!: bound page size on the workspaces list endpoint - #28040

Draft
jscottmiller wants to merge 1 commit into
mainfrom
scott/plat-386-bound-workspace-pagination
Draft

feat!: bound page size on the workspaces list endpoint#28040
jscottmiller wants to merge 1 commit into
mainfrom
scott/plat-386-bound-workspace-pagination

Conversation

@jscottmiller

Copy link
Copy Markdown
Contributor

GET /api/v2/workspaces treated an omitted or zero limit as "no limit" and passed it to SQL as NULL. It now resolves an omitted limit to 100 and rejects limit=0 or limit>100 with a 400. Only this endpoint changes: the shared coderd.ParsePagination is untouched, and ParsePaginationBounded is a second entry point used by the workspaces handler alone. Other list endpoints get bounded individually, later.

Breaking: a client that omitted limit to fetch every workspace now receives the first 100. limit=0 is rejected.

Callers that relied on one unbounded request now page to exhaustion through codersdk.Client.AllWorkspaces or API.getAllWorkspaces; callers that only read the total request a single row. Both helpers advance the offset by the requested page size and stop when it reaches the response count — not on a short page. A page can be short without the set being exhausted, because convertWorkspaces drops workspaces whose latest build or template the requester cannot read after LIMIT/OFFSET were applied in SQL. len(page) < pageSize truncates silently and offset += len(page) duplicates rows; both patterns existed in the tree and are fixed here.

Plan and deferred work

Server: codersdk.WorkspacesPageLimit = 100 (also generated into typesGenerated.ts), ParsePaginationBounded used only by the workspaces handler, swagger and docs/reference/api/workspaces.md regenerated. An out-of-range limit is rejected rather than clamped so a caller never silently receives fewer rows than it asked for.

Callers routed through the paging helpers: cli/list.go (QueryConvertWorkspaces, so coder list and coder schedule), cli/ssh.go completions, cli/configssh.go, both cli/exp_scaletest.go helpers, scaletest/prebuilds/run.go (duplicate local helper deleted), both codersdk/toolsdk sites, and the frontend agents pages plus useWorkspacesToBeDeleted. support keeps its own capped loop, now with page size min(cap, 100) and count-based termination. Count-only callers (UsageIndicator, TemplatePageHeader, DisableWorkspaceSharingDialog) send limit: 1.

An omitted limit defaults rather than erroring because ~108 client.Workspaces call sites in tests omit it; erroring would turn this into a repo-wide edit and a harsher external break for no added safety.

Deliberately out of scope: bounding any other endpoint (provisionerjobs, provisionerdaemons, exp_chats, agentfirewall, members, audit, AIBridge, template ACL), enterprise/cli/groupedit.go user paging, the undetectable truncation in /templates/{template}/acl/available, unbounded offset and deep-offset cost, and cursor (AfterID) paging. Recorded with the rest of the abandoned broad-bound attempt in coder/scott-misc, notes/PLAT-386-pagination-dead-ends.md.

Tests: TestPaginationBounded, endpoint-level TestWorkspacesPageLimit, TestAllWorkspaces, and getAllWorkspaces vitest cases covering offset progression, short pages, empty results, and caller-supplied pagination being overridden.


Created with Coder Agents on behalf of @jscottmiller.

GET /api/v2/workspaces now resolves an omitted limit to 100 and rejects
limit=0 or limit>100 instead of returning every row. The shared
ParsePagination and every other list endpoint are unchanged.

Callers that previously relied on a single unbounded request now page to
exhaustion through codersdk.Client.AllWorkspaces or API.getAllWorkspaces,
which advance the offset by the requested page size and stop when the
offset reaches the count the server reports. Callers that only read the
total request a single row.
@linear-code

linear-code Bot commented Aug 11, 2026

Copy link
Copy Markdown

PLAT-386

@github-actions

Copy link
Copy Markdown

Docs preview

Check off each page once it's been reviewed. If a page changes in a later push, its checkbox clears automatically so it gets a fresh look. Pages not yet wired into the docs navigation aren't listed here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant