Skip to content

Commit 8ee5955

Browse files
committed
fix(v2): name the undecodable-cursor failure on the two sortless lists
GET /workflows/{id}/versions and GET /workspaces/{id}/members threw a bare 'Invalid cursor' literal where every other v2 list uses a shared constant. The right one is UNREADABLE_CURSOR_MESSAGE, not INVALID_CURSOR_MESSAGE: both lists take only limit and cursor, so naming sortBy/sortOrder would answer one 400 with advice that earns a second. Their missing filter scope is correct and stays. Neither contract accepts a filter — v2PaginationFields is the whole query — so there is nothing to bind, and limit is excluded from a scope by design. Pins the message on the versions route, verified to fail against the literal.
1 parent 405933f commit 8ee5955

3 files changed

Lines changed: 11 additions & 2 deletions

File tree

apps/sim/app/api/v2/workflows/[id]/versions/route.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
} from '@sim/testing'
1313
import { NextRequest } from 'next/server'
1414
import { beforeEach, describe, expect, it, vi } from 'vitest'
15+
import { UNREADABLE_CURSOR_MESSAGE } from '@/lib/api/cursor-binding'
1516

1617
const mocks = vi.hoisted(() => ({
1718
listVersions: vi.fn(),
@@ -103,6 +104,12 @@ describe('GET /api/v2/workflows/[id]/versions', () => {
103104

104105
expect(response.status).toBe(400)
105106
expect(mocks.listVersions).not.toHaveBeenCalled()
107+
/**
108+
* The undecodable-token message, not the sort-mismatch one: this list
109+
* declares no `sortBy`/`sortOrder`, so naming them would answer a 400 with
110+
* advice that earns a second.
111+
*/
112+
expect((await response.json()).error.message).toBe(UNREADABLE_CURSOR_MESSAGE)
106113
})
107114

108115
/**

apps/sim/app/api/v2/workflows/[id]/versions/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import {
33
v2ListWorkflowVersionsContract,
44
v2WorkflowVersionCursorSchema,
55
} from '@/lib/api/contracts/v2/workflows'
6+
import { UNREADABLE_CURSOR_MESSAGE } from '@/lib/api/cursor-binding'
67
import { defineV2JsonRoute, v2ApiKeyAuth, v2RateLimits } from '@/lib/api/server/routes'
78
import { OrchestrationError } from '@/lib/core/orchestration/types'
89
import { v2WorkflowErrorPolicies } from '@/lib/workflows/api'
@@ -24,7 +25,7 @@ export const GET = defineV2JsonRoute({
2425
? v2WorkflowVersionCursorSchema.safeParse(decodeCursor(query.cursor))
2526
: undefined
2627
if (decoded && !decoded.success) {
27-
throw new OrchestrationError('validation', 'Invalid cursor')
28+
throw new OrchestrationError('validation', UNREADABLE_CURSOR_MESSAGE)
2829
}
2930
return {
3031
workflowId: params.id,

apps/sim/app/api/v2/workspaces/[workspaceId]/members/route.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import {
22
v2ListWorkspaceMembersContract,
33
v2WorkspaceMemberCursorSchema,
44
} from '@/lib/api/contracts/v2/workspaces'
5+
import { UNREADABLE_CURSOR_MESSAGE } from '@/lib/api/cursor-binding'
56
import {
67
defineV2JsonRoute,
78
v2ApiKeyAuth,
@@ -25,7 +26,7 @@ export const GET = defineV2JsonRoute({
2526
? v2WorkspaceMemberCursorSchema.safeParse(decodeCursor(query.cursor))
2627
: undefined
2728
if (decoded && !decoded.success) {
28-
throw new OrchestrationError('validation', 'Invalid cursor')
29+
throw new OrchestrationError('validation', UNREADABLE_CURSOR_MESSAGE)
2930
}
3031
return {
3132
workspaceId: params.workspaceId,

0 commit comments

Comments
 (0)