Problem
gog gmail search and gog gmail messages search give a caller no way to learn how large a result set is without walking it. The JSON payload is items + nextPageToken, so "are there more?" is answerable but "how many more?" is not.
That gap causes a specific, repeatable failure in agent/LLM callers: a capped page gets read as the complete answer, and the caller reports that a message does not exist when it does. A page token alone is easy to skim past; a magnitude is not.
Why the obvious fix doesn't work
The Gmail API returns resultSizeEstimate on both users.threads.list and users.messages.list, and gog currently drops it — gmail_search.go:~97 and gmail_messages.go:~110 build the JSON payload by hand from items + nextPageToken.
Surfacing that field would be a bug, not a fix. It saturates. Measured on a live account, gog v0.35.0 (402def5), 2026-08-12:
$ gog api call gmail v1 users.messages.list \
--params '{"userId":"me","q":"<Q>","maxResults":1,"fields":"resultSizeEstimate"}'
| query |
resultSizeEstimate |
true count (--all) |
from:freshbooks.com |
201 |
21 |
from:housecallpro.com |
201 |
6 |
from:thumbtack.com newer_than:30d |
201 |
3 |
from:honeybook.com |
201 |
9 |
invoice |
201 |
>500 |
in:inbox |
201 |
large |
zzzznomatch |
0 |
0 |
It returns 201 for every non-empty query and 0 for an empty one — a has-results boolean wearing a number's clothes. It is also independent of maxResults (identical at 1, 10, and 100), so it isn't a per-page figure either. Emitting it would let a caller report "3 of ~201" when the truth is 3 of 6.
Proposed fix
An opt-in --count flag on both search commands that reports a real number, obtained with one extra list call requesting a single maximal page of bare ids:
maxResults=500, fields="threads/id,nextPageToken" (or messages/id)
- fits in one page → exact total, emitted as
totalMatches
- fills the page with more behind it → honest lower bound, emitted as
totalMatchesAtLeast
Verified against the same account:
| query |
probe result |
matches --all? |
from:freshbooks.com |
counted 21, no more pages |
✅ 21 |
from:housecallpro.com |
counted 6, no more pages |
✅ 6 |
invoice |
counted 500, more pages |
✅ lower bound |
The response is ids only, so it stays small, and the flag keeps it off the default path — no extra round-trip for callers who don't ask.
Exact whenever the set fits a page, which is the common case and always the case for the narrow queries a false negative is most likely to come from.
Notes
- I have this implemented and validated in a downstream wrapper already; happy to send the
--count PR here (branch in progress) if the shape looks right to you.
- Open question for a maintainer: whether
--count should also print on the text/table path, or stay JSON-only.
Problem
gog gmail searchandgog gmail messages searchgive a caller no way to learn how large a result set is without walking it. The JSON payload is items +nextPageToken, so "are there more?" is answerable but "how many more?" is not.That gap causes a specific, repeatable failure in agent/LLM callers: a capped page gets read as the complete answer, and the caller reports that a message does not exist when it does. A page token alone is easy to skim past; a magnitude is not.
Why the obvious fix doesn't work
The Gmail API returns
resultSizeEstimateon bothusers.threads.listandusers.messages.list, andgogcurrently drops it —gmail_search.go:~97andgmail_messages.go:~110build the JSON payload by hand from items +nextPageToken.Surfacing that field would be a bug, not a fix. It saturates. Measured on a live account, gog
v0.35.0 (402def5), 2026-08-12:resultSizeEstimate--all)from:freshbooks.comfrom:housecallpro.comfrom:thumbtack.com newer_than:30dfrom:honeybook.cominvoicein:inboxzzzznomatchIt returns 201 for every non-empty query and 0 for an empty one — a has-results boolean wearing a number's clothes. It is also independent of
maxResults(identical at 1, 10, and 100), so it isn't a per-page figure either. Emitting it would let a caller report "3 of ~201" when the truth is 3 of 6.Proposed fix
An opt-in
--countflag on both search commands that reports a real number, obtained with one extra list call requesting a single maximal page of bare ids:totalMatchestotalMatchesAtLeastVerified against the same account:
--all?from:freshbooks.comfrom:housecallpro.cominvoiceThe response is ids only, so it stays small, and the flag keeps it off the default path — no extra round-trip for callers who don't ask.
Exact whenever the set fits a page, which is the common case and always the case for the narrow queries a false negative is most likely to come from.
Notes
--countPR here (branch in progress) if the shape looks right to you.--countshould also print on the text/table path, or stay JSON-only.