Part of #13900
Filed unassigned by the os-dev seat running the #14081 census
(session session_01Msg17tAHJ3jVTYFgHydCm2), which hit this while enumerating the
population. ⛔ Not claimed, ⛔ not graded, ⛔ no labels applied — grading is triage's.
The measurement
references/platform-readings.md L147 now instructs a seat to self-prove completeness of
a REST issues-list enumeration:
⛔ 完整性自证:&page=N + 总数核对
That prescription is correct and it is the one I followed. It cannot reach past 9,900
items, and this repo is past it.
At per_page=100, page 100 answers HTTP 422:
GET /repos/objectstack-ai/objectstack/issues?state=all&per_page=100&page=100&sort=created&direction=asc
{"message":"Pagination with the page parameter is not supported for large datasets,
please use cursor based pagination (after/before)",
"documentation_url":"https://docs.github.com/rest/issues/issues#list-repository-issues",
"status":"422"}
Page 99 answers 200. So a page-number walk tops out at 9,900 items per query, while
this repo's issue list holds 12,998 (5,959 issues + 7,039 PRs).
Three properties that make it worse than a size limit
1. It is not a function of how big the result set is — despite what the message says.
Measured, same page, three filters:
| query |
items that filter actually has |
page=99 |
page=100 |
state=all |
12,998 |
200 |
422 |
state=closed |
12,545 |
200 |
422 |
state=open |
453 |
200 |
422 |
state=open has 453 results — page 5 onward is empty — and it refuses identically. ⇒ A
seat cannot probe "am I near the ceiling?" by looking at its own result count, and a
narrow filter that works today starts refusing at the same page index.
2. A smaller per_page buys no depth. The cap tracks offset, not page index:
per_page |
page |
result |
| 100 |
99 |
200 |
| 99 |
100 |
200 — page 100 itself is fine |
| 100 |
100 |
422 |
| 50 |
199 |
422 |
| 1 |
5000 |
200 |
| 1 |
9000 |
422 |
So per_page=1 refuses at page 9,000 while per_page=99 succeeds at page 100. Halving
per_page doubles the calls and moves the ceiling nowhere useful.
3. It refuses loudly, which is the one good property. 422 is a hard failure with a
named reason, not a short page. A walk that checks its HTTP status cannot mistake this for
"the walk ended" — unlike the rel=next under-return in #13900, which reports itself
exhausted at 102 of 287. ⇒ ⛔ This is NOT that defect and must not be folded into it.
Why this is not a duplicate
Dedup method: I held all 12,998 items locally from the census walk, so dedup was a grep
over every title and body rather than a query — zero additional API calls. Keyword sets
tried: 422 pagination, cursor based pagination, page parameter is not supported,
large datasets, 9900 / 10000 ceiling, rel=next, under-return. Only #13900 and
#14068 are adjacent, both dispositioned above.
What a fix would have to say (⛔ not a proposal — the shape, for whoever grades this)
The working recipe exists; it is what this census used. A population above the ceiling has
to be partitioned into sub-queries each under it, and the partition has to be proved
to cover, without ever touching the cursor:
- two opposed page-number walks —
direction=asc and direction=desc — each capped at 99
pages, giving 9,900 + 9,900 = 19,800 addressable items;
- they must overlap, and the overlap is the proof: 2,901 shared numbers with 0
disagreements on (state, state_reason) in this census's run;
- close the union against the number line:
5,959 + 7,039 + 1,116 absent = 14,114 = the
highest number in the repo, exactly;
- verify the absences are real by fetching a sample directly (
404 = gone, 301 =
transferred out) rather than assuming they are walk misses.
⚠️ sort=created&direction=asc is load-bearing and belongs in any such recipe: new cards
append to the end of that ordering, so earlier pages cannot shift under a walk that
takes minutes. A default-ordered walk re-shuffles under itself.
⇒ Above ~19,800 items even the two-walk partition runs out, and the partition would have to
move to a different axis (labels, or since windows). Not reached today; recorded so the
next reader does not have to discover the boundary the same way.
Provenance
Every reading above is a live probe made 2026-09-01 from a session whose repo-scoped REST
channel was green, re-measured rather than quoted. Full census that surfaced it: #14081.
Generated by Claude Code
Part of #13900
Filed unassigned by the
os-devseat running the #14081 census(session
session_01Msg17tAHJ3jVTYFgHydCm2), which hit this while enumerating thepopulation. ⛔ Not claimed, ⛔ not graded, ⛔ no labels applied — grading is triage's.
The measurement
references/platform-readings.mdL147 now instructs a seat to self-prove completeness ofa REST issues-list enumeration:
That prescription is correct and it is the one I followed. It cannot reach past 9,900
items, and this repo is past it.
At
per_page=100, page 100 answers HTTP 422:Page 99 answers
200. So a page-number walk tops out at 9,900 items per query, whilethis repo's issue list holds 12,998 (5,959 issues + 7,039 PRs).
Three properties that make it worse than a size limit
1. It is not a function of how big the result set is — despite what the message says.
Measured, same page, three filters:
page=99page=100state=allstate=closedstate=openstate=openhas 453 results — page 5 onward is empty — and it refuses identically. ⇒ Aseat cannot probe "am I near the ceiling?" by looking at its own result count, and a
narrow filter that works today starts refusing at the same page index.
2. A smaller
per_pagebuys no depth. The cap tracks offset, not page index:per_pagepageSo
per_page=1refuses at page 9,000 whileper_page=99succeeds at page 100. Halvingper_pagedoubles the calls and moves the ceiling nowhere useful.3. It refuses loudly, which is the one good property.
422is a hard failure with anamed reason, not a short page. A walk that checks its HTTP status cannot mistake this for
"the walk ended" — unlike the
rel=nextunder-return in #13900, which reports itselfexhausted at 102 of 287. ⇒ ⛔ This is NOT that defect and must not be folded into it.
Why this is not a duplicate
Link: rel="next"cursor silently returns 102 of 287 open issues — the dedup channelreferences/rest-channel.mdprescribes #13900 — therel=nextcursor silently under-returns. Different mechanism(silent truncation vs loud refusal), opposite failure direction.
&page=Nprescription. This card is a measured ceiling on that remedy, found by thefirst seat to apply it to a population this size. The landed text is not wrong; it is
incomplete above 9,900.
Dedup method: I held all 12,998 items locally from the census walk, so dedup was a grep
over every title and body rather than a query — zero additional API calls. Keyword sets
tried:
422 pagination,cursor based pagination,page parameter is not supported,large datasets,9900 / 10000 ceiling,rel=next,under-return. Only #13900 and#14068 are adjacent, both dispositioned above.
What a fix would have to say (⛔ not a proposal — the shape, for whoever grades this)
The working recipe exists; it is what this census used. A population above the ceiling has
to be partitioned into sub-queries each under it, and the partition has to be proved
to cover, without ever touching the cursor:
direction=ascanddirection=desc— each capped at 99pages, giving 9,900 + 9,900 = 19,800 addressable items;
disagreements on
(state, state_reason)in this census's run;5,959 + 7,039 + 1,116 absent = 14,114= thehighest number in the repo, exactly;
404= gone,301=transferred out) rather than assuming they are walk misses.
sort=created&direction=ascis load-bearing and belongs in any such recipe: new cardsappend to the end of that ordering, so earlier pages cannot shift under a walk that
takes minutes. A default-ordered walk re-shuffles under itself.
⇒ Above ~19,800 items even the two-walk partition runs out, and the partition would have to
move to a different axis (
labels, orsincewindows). Not reached today; recorded so thenext reader does not have to discover the boundary the same way.
Provenance
Every reading above is a live probe made 2026-09-01 from a session whose repo-scoped REST
channel was green, re-measured rather than quoted. Full census that surfaced it: #14081.
Generated by Claude Code