Skip to content

Conversation

@janb87
Copy link
Contributor

@janb87 janb87 commented Oct 31, 2025

Summary

  • extend the regression test covering a token query whose only field uses @fetchAll so it also verifies no extra non-list request is issued
  • ensure paginated results create parent containers before setting list data
  • skip executing non-list GraphQL requests when no fields remain after removing @fetchAll

Testing

  • bun test sdk/thegraph/src/utils/pagination.test.ts (fails: missing dependency gql.tada because packages cannot be downloaded in the execution environment)

https://chatgpt.com/codex/tasks/task_b_6904799dd93883208eb61e4f90b5c5ab

Summary by Sourcery

Prevent empty non-list queries during @fetchall pagination by checking for executable fields and extend tests to cover queries with only fetchAll lists

Bug Fixes:

  • Skip executing non-list GraphQL queries when no executable fields remain after removing @fetchall

Enhancements:

  • Add countExecutableFields helper to detect and skip empty queries
  • Refactor createNonListQuery to prune fields without selections on leave

Tests:

  • Add test to verify queries with only @fetchall list fields skip non-list requests and return paged data

Note

Skips executing non-list GraphQL requests when only @fetchall list fields remain, with AST pruning and a regression test to verify behavior.

  • Pagination utils:
    • createNonListQuery(...): removes list fields and prunes empty selection sets; always returns a filtered document.
    • countExecutableFields(...): new helper to detect empty documents; used to skip non-list requests when no executable fields remain.
    • Minor: import FieldNode for leave-visitor pruning.
  • Tests:
    • Add regression test ensuring a query with only @fetchAll list fields returns data and does not issue an extra non-list request.

Written by Cursor Bugbot for commit 95573b2. This will update automatically on new commits. Configure here.

@github-actions
Copy link

github-actions bot commented Oct 31, 2025

📦 Packages

Package NPM Docker
SDK Cli @settlemint/sdk-cli@2.6.2-pr673e46be
SDK The Graph @settlemint/sdk-thegraph@2.6.2-pr673e46be
SDK Portal @settlemint/sdk-portal@2.6.2-pr673e46be
SDK Hasura @settlemint/sdk-hasura@2.6.2-pr673e46be
SDK JS @settlemint/sdk-js@2.6.2-pr673e46be
SDK Utils @settlemint/sdk-utils@2.6.2-pr673e46be
SDK Next @settlemint/sdk-next@2.6.2-pr673e46be
SDK Minio @settlemint/sdk-minio@2.6.2-pr673e46be
SDK IPFS @settlemint/sdk-ipfs@2.6.2-pr673e46be
SDK Blockscout @settlemint/sdk-blockscout@2.6.2-pr673e46be
SDK MCP @settlemint/sdk-mcp@2.6.2-pr673e46be
SDK Viem @settlemint/sdk-viem@2.6.2-pr673e46be
SDK EAS @settlemint/sdk-eas@2.6.2-pr673e46be

@github-actions github-actions bot added qa:success QA workflow passed successfully chore Maintenance tasks status:draft Pull request is in draft status labels Oct 31, 2025
@janb87 janb87 changed the title Skip empty non-list queries during fetchAll pagination fix: skip empty non-list queries during fetchAll pagination Oct 31, 2025
@github-actions github-actions bot added qa:failed QA workflow failed and removed qa:success QA workflow passed successfully labels Oct 31, 2025
@janb87 janb87 marked this pull request as ready for review October 31, 2025 14:38
@github-actions github-actions bot added qa:running QA workflow is currently running and removed qa:failed QA workflow failed labels Oct 31, 2025
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • Consider combining the pruning in createNonListQuery with the executable-field counting into a single AST visit to eliminate the extra traversal and streamline the logic.
  • Instead of always returning a filtered document and relying on countExecutableFields externally, have createNonListQuery itself return null when no executable fields remain to simplify its API.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- Consider combining the pruning in createNonListQuery with the executable-field counting into a single AST visit to eliminate the extra traversal and streamline the logic.
- Instead of always returning a filtered document and relying on countExecutableFields externally, have createNonListQuery itself return null when no executable fields remain to simplify its API.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@github-actions github-actions bot added qa:success QA workflow passed successfully status:ready-for-review Pull request is ready for review and removed qa:running QA workflow is currently running status:draft Pull request is in draft status labels Oct 31, 2025
@github-actions
Copy link

github-actions bot commented Oct 31, 2025

To view in Slack, search for: 1761921589.180549

@github-actions
Copy link

github-actions bot commented Oct 31, 2025

To view in Slack, search for: 1761921613.129709

@github-actions github-actions bot added status:draft Pull request is in draft status and removed status:ready-for-review Pull request is ready for review labels Oct 31, 2025
@coderabbitai
Copy link

coderabbitai bot commented Oct 31, 2025

📝 Walkthrough

Walkthrough

This change enhances pagination logic in the GraphQL utility. A new test case validates behavior when only @fetchAll fields are requested in queries. The implementation introduces a countExecutableFields helper function to count non-underscore fields with executable content. Non-list field handling is refactored to remove the hasFields flag and tighten field filtering logic. The main pagination flow now uses executable field counting to short-circuit non-list queries when they would be empty, avoiding unnecessary requests while preserving existing per-field pagination behavior.

Pre-merge checks

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 66.67% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title "fix: skip empty non-list queries during fetchAll pagination" accurately captures the main objective of this pull request. The changes introduce a countExecutableFields helper and modify the pagination flow to detect and skip non-list GraphQL requests when no executable fields remain after removing @fetchall fields, which is precisely what the title conveys. The title is concise, clear, and directly related to the primary fix being implemented.
Description Check ✅ Passed The pull request description is directly related to the changeset and provides specific, meaningful information about the changes. The description accurately summarizes the three main aspects of the changes: (1) extending the regression test to verify no extra non-list request is issued for queries with only @fetchall fields, which aligns with the new test case in pagination.test.ts; (2) ensuring paginated results create parent containers, which corresponds to the refactored non-list query handling in pagination.ts; and (3) skipping non-list GraphQL requests when no executable fields remain, which directly reflects the introduction of the countExecutableFields helper and early-return logic. The description uses specific technical terminology and clearly conveys the intent of the changeset rather than being vague or generic.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 6df0c36 and 95573b2.

📒 Files selected for processing (2)
  • sdk/thegraph/src/utils/pagination.test.ts (1 hunks)
  • sdk/thegraph/src/utils/pagination.ts (3 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{ts,tsx}: Do not use default exports in TypeScript (except when a framework requires it)
Use import type for type-only imports in TypeScript
Prefer interfaces over type aliases for object shapes
Never use any; use unknown or proper types instead
Use discriminated unions for error handling
File names should be kebab-case
Use camelCase for variable and function names
Use PascalCase for types, interfaces, and classes
Use UPPER_SNAKE_CASE for constants
Prefer nullish coalescing (??) over logical OR (||)
Use early returns to reduce nesting
Extract complex logic into well-named functions
Keep functions small and focused
Use structured logging with proper context

**/*.{ts,tsx}: Inside generic functions, using any for concise type narrowing is acceptable; outside of generics, use any extremely sparingly
Avoid default exports unless explicitly required by the framework (e.g., Next.js pages)
Use discriminated unions to model variant data and avoid 'bag of optionals'
Handle discriminated unions with switch statements over the discriminant
Do not introduce new enums; prefer as const objects for enum-like behavior; retain existing enums
Use top-level import type when importing types instead of inline import { type ... }
Prefer interface extends over intersection types (&) for modeling inheritance; use & only when extends is not possible
Use JSDoc comments to annotate functions and types when behavior isn’t obvious; keep comments concise
Use JSDoc inline @link to reference related functions and types within the same file
File names should be kebab-case (e.g., my-component.ts)
Use camelCase for variables and function names
Use UpperCamelCase (PascalCase) for classes, types, and interfaces
Use ALL_CAPS for constants (and enum values where enums already exist)
Prefix generic type parameters with T (e.g., TKey, TValue)
Be mindful of noUncheckedIndexedAccess: treat indexed object/array access as possibly undefined
Use optional properties sparingly; prefer required prop...

Files:

  • sdk/thegraph/src/utils/pagination.test.ts
  • sdk/thegraph/src/utils/pagination.ts
sdk/{viem,portal,thegraph,eas,blockscout,js}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

sdk/{viem,portal,thegraph,eas,blockscout,js}/**/*.{ts,tsx}: Always validate blockchain addresses before use
Handle chain-specific differences properly
Implement proper gas estimation for transactions
Use type-safe contract interactions (e.g., via Viem/Ethers types)

Files:

  • sdk/thegraph/src/utils/pagination.test.ts
  • sdk/thegraph/src/utils/pagination.ts
**/*.{test,spec}.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.{test,spec}.{ts,tsx}: Write unit tests using Vitest
Mock external API calls in tests
Test error scenarios explicitly

Files:

  • sdk/thegraph/src/utils/pagination.test.ts
**/*.{js,jsx,ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/bun.mdc)

Use Bun.File() for file reading and writing

Files:

  • sdk/thegraph/src/utils/pagination.test.ts
  • sdk/thegraph/src/utils/pagination.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (7)
  • GitHub Check: QA
  • GitHub Check: cubic · AI code reviewer
  • GitHub Check: Cursor Bugbot
  • GitHub Check: Sourcery review
  • GitHub Check: QA
  • GitHub Check: QA
  • GitHub Check: Sourcery review
🔇 Additional comments (1)
sdk/thegraph/src/utils/pagination.test.ts (1)

356-377: Appreciate the regression coverage

New test nails the scenario where only paginated fields are selected and ensures the client still returns structured data while tracking request count.

Comment on lines +284 to +291
Field: (node) => {
if (!node.name.value.startsWith("__")) {
if (!node.selectionSet || node.selectionSet.selections.length > 0) {
fieldCount += 1;
}
}
},
});
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Don't skip __typename-only follow-up queries

countExecutableFields ignores fields whose names start with "__", so a query like token { __typename holders @fetchAll { ... } } now short-circuits before the non-list request runs. The merged result never includes __typename, even though the caller explicitly asked for it. Previously we still executed the non-list fetch and returned the correct payload. Please count meta fields as executable (at least __typename) so we don't drop requested data.

Apply this diff to ensure __typename keeps the non-list query alive:

-    Field: (node) => {
-      if (!node.name.value.startsWith("__")) {
-        if (!node.selectionSet || node.selectionSet.selections.length > 0) {
-          fieldCount += 1;
-        }
-      }
-    },
+    Field: (node) => {
+      if (!node.selectionSet || node.selectionSet.selections.length > 0) {
+        fieldCount += 1;
+      }
+    },
🤖 Prompt for AI Agents
In sdk/thegraph/src/utils/pagination.ts around lines 284-291, the current logic
skips all fields whose names start with "__" causing queries that only request
__typename (e.g. token { __typename holders @fetchAll { ... } }) to
short-circuit and drop requested data; update the conditional so that meta
fields are still counted when executable, specifically treat "__typename" as
executable: do not exclude it from the fieldCount check (i.e., only skip
double-underscore fields except for "__typename"), and keep the existing
selectionSet/selections length check so __typename-only follow-up queries keep
the non-list query alive.

@github-actions github-actions bot added status:ready-for-review Pull request is ready for review and removed status:draft Pull request is in draft status labels Oct 31, 2025
Copy link

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files

Prompt for AI agents (all 1 issues)

Understand the root cause of the following 1 issues and fix them.


<file name="sdk/thegraph/src/utils/pagination.ts">

<violation number="1" location="sdk/thegraph/src/utils/pagination.ts:285">
countExecutableFields excludes meta fields like __typename, which can cause the non-list request to be skipped and omit requested data when __typename is the only remaining field. Include __typename in the count so the follow-up query executes.</violation>
</file>

React with 👍 or 👎 to teach cubic. Mention @cubic-dev-ai to give feedback, ask questions, or re-run the review.


visit(document, {
Field: (node) => {
if (!node.name.value.startsWith("__")) {
Copy link

@cubic-dev-ai cubic-dev-ai bot Oct 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

countExecutableFields excludes meta fields like __typename, which can cause the non-list request to be skipped and omit requested data when __typename is the only remaining field. Include __typename in the count so the follow-up query executes.

Prompt for AI agents
Address the following comment on sdk/thegraph/src/utils/pagination.ts at line 285:

<comment>countExecutableFields excludes meta fields like __typename, which can cause the non-list request to be skipped and omit requested data when __typename is the only remaining field. Include __typename in the count so the follow-up query executes.</comment>

<file context>
@@ -263,17 +262,35 @@ function createNonListQuery(document: DocumentNode, listFields: ListFieldWithFet
+
+  visit(document, {
+    Field: (node) =&gt; {
+      if (!node.name.value.startsWith(&quot;__&quot;)) {
+        if (!node.selectionSet || node.selectionSet.selections.length &gt; 0) {
+          fieldCount += 1;
</file context>
Fix with Cubic

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

Labels

chore Maintenance tasks codex qa:success QA workflow passed successfully status:ready-for-review Pull request is ready for review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants