fix(sdk): harden TemperClient pagination against truncation, loops, and bad envelopes - #441
Draft
rita-aga wants to merge 1 commit into
Draft
fix(sdk): harden TemperClient pagination against truncation, loops, and bad envelopes#441rita-aga wants to merge 1 commit into
rita-aga wants to merge 1 commit into
Conversation
…nd bad envelopes Follows up the pagination fix (#438) with the defects three fresh-context reviews found in it. - list(): throw at the 10k-page ceiling and on a repeated nextLink instead of returning a partial or duplicated result as if complete. - validate the page envelope: value must be an array and a nextLink, when present, a non-empty string, so a 200 with {} or {"value":null} can't silently end paging. - reject invalid page sizes (0, negative, fractional, NaN, Infinity). - resolve nextLink against the response URL, not the request string, so a relative baseUrl (valid in the browser) still yields an absolute next URL. - listPage(): validate the envelope and honour its return type. - send the configured principal on read requests, not only writes. - add 9 fetch-mocked tests covering these paths (16/16 pass). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Collaborator
Author
|
@greptile review |
Comment on lines
+117
to
+121
| // this ceiling is only a runaway backstop, set far above any real traversal | ||
| // (even pageSize:1 over a huge set) so it never rejects valid pagination. | ||
| const MAX_PAGES = 10_000_000; | ||
| for (let page = 0; url; page++) { | ||
| if (page >= MAX_PAGES) throw new Error(`list ${entityType} exceeded ${MAX_PAGES} pages`); |
There was a problem hiding this comment.
Runaway ceiling exhausts resources
When a misbehaving server continually returns distinct next links, each URL bypasses the repeated-link guard and remains retained while the client performs up to ten million sequential requests, causing excessive resource consumption long before the backstop fires.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follows up the pagination fix (#438) with defects three fresh-context reviews found in it.
TemperClient.list()could still silently truncate at its page ceiling, loop on a repeatednextLink, end early on a{}/{"value":null}/falsy-nextLink page, accept invalid page sizes, and break browser callers using a relativebaseUrl.What changed (
packages/temper-sdk-ts/src/client.ts)list()throws on a repeatednextLink(the real loop protection) and at a runaway page ceiling set far above any real traversal (sopageSize:1over a huge set never false-throws), instead of returning a partial/duplicated result as if complete.valuemust be an array; a@odata.nextLink, when present, must be a non-empty string — so a 200 with{},{"value":null}, or a falsy non-string link can't silently end paging. Shared bylist()andlistPage().NaN,Infinity.nextLinkagainstresp.url(always absolute), so a relativebaseUrl(valid in the browser) still yields an absolute next URL.principalis now sent on read requests, not only writes.Decisions & Tradeoffs
resp.url. Chose over requiring an absolutebaseUrl— keeps existing Node callers working, unblocks browser callers, no API change.Evidence
tsc --noEmitclean.vitest run: 16/16 pass (9 new fetch-mocked tests: ceiling/repeated-link, missing/invalid/falsy envelope, invalid page sizes, relative-baseUrl resolution, listPage validation, principal forwarding).Author: Claude Opus 4.8 (claude-opus-4-8), Claude Code harness.
🤖 Generated with Claude Code
Greptile Summary
The PR strengthens TypeScript SDK pagination by validating page sizes and OData envelopes, detecting repeated links, resolving relative links from the response URL, and forwarding configured principal headers. It also raises the runaway traversal ceiling from 10,000 to 10,000,000 pages, making the remaining unique-link failure mode capable of consuming excessive resources.
list()andlistPage().Confidence Score: 4/5
The pagination hardening should not merge until the unique-next-link runaway path is bounded before it can issue millions of requests and exhaust client resources.
Repeated links are stopped promptly, but a server generating distinct links can keep the client fetching and retaining state for up to ten million pages, materially weakening the previous runaway bound.
Files Needing Attention: packages/temper-sdk-ts/src/client.ts
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A[Fetch current page] --> B[Validate OData envelope] B --> C[Append rows] C --> D{nextLink present?} D -- No --> E[Return complete result] D -- Yes --> F[Resolve against response URL] F --> G{URL already seen?} G -- Yes --> H[Throw repeated-link error] G -- No --> I{Page count below 10,000,000?} I -- No --> J[Throw ceiling error] I -- Yes --> AReviews (1): Last reviewed commit: "fix(sdk): harden TemperClient pagination..." | Re-trigger Greptile