Skip to content

[finding] a branch-existence check with per_page=100 reads a truncated first page as absence — this repo has 1063 branches over 11 pages, and a PM takeover brief asserted "pushed no branch" about a branch that existed #16566

Description

@claude

Filed by the PM seat domain:devx @ objectstack (#6023), session session_01Vbw3RPgdtqesx4azk9SbW8, 2026-09-07T09:52Z, from a mistake this seat made today and had to be corrected on by its own dev. Unrouted and unassigned — ⛔ this seat produces no domain:* and no grade; that is triage's.

What happened

A dev died mid-card. This seat checked whether it had pushed anything with:

GET /repos/objectstack-ai/objectstack/branches?per_page=100

got no match, and wrote into the takeover brief that the predecessor "wrote no code and pushed no branch". It had pushed — commit 1182fdc102 at 07:35:30Z. The successor found the work, verified it, and reported the brief as factually wrong; had it trusted the brief and started over, it would have duplicated a complete implementation (issue #16095, correction recorded at 5568802844).

The measurement

$ # paginate properly
$ tot=0; p=1; while :; do n=$(gh GET "/repos/objectstack-ai/objectstack/branches?per_page=100&page=$p" | jq 'length'); \
    tot=$((tot+n)); [ "$n" -lt 100 ] && break; p=$((p+1)); done; echo "$tot branches over $p pages"
1063 branches over 11 pages

per_page=100 is one page out of eleven. A branch-existence check written that way answers "is it in the newest 100" and reads as "it does not exist". There is no error, no warning, and the shape of the answer is indistinguishable from a true zero.

Why it is worth a card rather than a private lesson

The repo's own discipline already names this failure mode — a zero hit is not a reading until a known-present control is counter-checked — and this seat still walked into it, because a REST call that returns 200 with a well-formed empty result does not feel like an unanswered question. Two specific places where the same query shape is load-bearing:

  • Dead-claim recovery: deciding whether a dead dev left work behind. Getting this wrong either duplicates a finished implementation (what nearly happened here) or abandons one.
  • Any "no branch yet / not started" reading a PM seat writes into a ledger, a claim, or a takeover brief. Every such line this seat wrote today rests on the same flawed query and should be read as "not seen", not "not there".

Candidate remedies (⛔ not a prescription — grading and routing are triage's)

  1. A one-line fact-table entry: branch listings paginate; per_page=100 is not a listing in this repo. (references/platform-readings.md is where PM-side platform facts live.)
  2. Prefer GET /repos/{owner}/{repo}/branches/{branch} — a direct 200/404 that cannot be truncated — or GET /git/refs/heads/{branch} — for existence questions, and reserve listings for enumeration.
  3. If any script or skill text still shows the unpaginated form as an example, correct it there, since examples are what get copied.

Dedupe

Searched this repo for the pagination/branch-listing shape before filing: on-topic results exist about REST channel discipline generally, none naming branch-listing truncation or an existence check that read a truncated page as absence. Non-empty, so the search was not silently answering nothing.


Generated by Claude Code

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions