Skip to content

Commit a4f805f

Browse files
waleedlatif1claude
andcommitted
fix(dagster): make list_assets hasMore exact via fetch N+1
Address PR review (hasMore true on exact page): request one extra row (pageSize + 1), use its presence as the authoritative hasMore, slice it off, and derive the returned cursor from the last RETURNED asset's key path (JSON-serialized; Dagster normalizes JS/Python whitespace on the way in). This removes the false-positive hasMore when the final page is exactly full. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 63a52b6 commit a4f805f

1 file changed

Lines changed: 14 additions & 7 deletions

File tree

apps/sim/tools/dagster/list_assets.ts

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,9 @@ export const listAssetsTool: ToolConfig<DagsterListAssetsParams, DagsterListAsse
8181
method: 'POST',
8282
headers: (params) => dagsterRequestHeaders(params),
8383
body: (params) => {
84-
const variables: Record<string, unknown> = {
85-
limit: params.limit ?? DEFAULT_LIST_ASSETS_LIMIT,
86-
}
84+
const pageSize = params.limit ?? DEFAULT_LIST_ASSETS_LIMIT
85+
// Request one extra row so `hasMore` is exact even when the final page is exactly `pageSize` long.
86+
const variables: Record<string, unknown> = { limit: pageSize + 1 }
8787
if (params.prefix) variables.prefix = parseAssetKeyPath(params.prefix)
8888
if (params.cursor) variables.cursor = params.cursor
8989
return { query: LIST_ASSETS_QUERY, variables }
@@ -102,18 +102,25 @@ export const listAssetsTool: ToolConfig<DagsterListAssetsParams, DagsterListAsse
102102
throw new Error(dagsterUnionErrorMessage(result, 'List assets failed'))
103103
}
104104

105-
const assets = result.nodes.map((node) => ({
105+
const pageSize = params?.limit ?? DEFAULT_LIST_ASSETS_LIMIT
106+
const hasMore = result.nodes.length > pageSize
107+
const pageNodes = hasMore ? result.nodes.slice(0, pageSize) : result.nodes
108+
109+
const assets = pageNodes.map((node) => ({
106110
assetKey: node.key.path.join('/'),
107111
path: node.key.path,
108112
}))
109113

110-
const limit = params?.limit ?? DEFAULT_LIST_ASSETS_LIMIT
114+
// Asset cursors are the JSON-serialized key path; Dagster normalizes JS/Python whitespace on the
115+
// way back in, so we derive the cursor from the last RETURNED asset (not the extra probe row).
116+
const lastPath = pageNodes.length > 0 ? pageNodes[pageNodes.length - 1].key.path : null
117+
111118
return {
112119
success: true,
113120
output: {
114121
assets,
115-
cursor: result.cursor ?? null,
116-
hasMore: assets.length >= limit,
122+
cursor: lastPath ? JSON.stringify(lastPath) : null,
123+
hasMore,
117124
},
118125
}
119126
},

0 commit comments

Comments
 (0)