GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — chore(api): remove a dead route builder, bound folder-index reads, reject invalid cursors by waleedlatif1 · Pull Request #6568 · simstudioai/sim

Conversation

@waleedlatif1

@waleedlatif1 waleedlatif1 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #6567 → #6565 → #6560. Review only this PR's own commits; merge after its parents.

Three independent tidies from the v2 parity audit, one commit each. All are incomplete application of new work rather than regressions from main.

1. Dead route builder and 27 dead endpoint labels

withPublicApiRouteHandler (~80 lines) had zero production callers — referenced only by its own test and two regexes in the audit script that existed to recognize it. It shipped in #5273 alongside 27 extra ApiEndpoint members, but the v2 surface actually runs on defineV2JsonRoute + v2RateLimits.publicApi.

Verified by string literal, not just by symbol: each of the 46 members was grepped as a bare string across apps/, packages/, and scripts/, then narrowed to the only two positions that reach telemetry (checkRateLimit, authenticateRequest). 19 are live and kept. The decisive fact is that v2RateLimits never reads an ApiEndpoint, so no removed label can be emitted by any v2 route.

Ratchet metrics are byte-identical before and after (1093 routes, 1093 Zod-backed, 0 non-Zod) — the builder lived outside a route.ts path, so it was never counted as a route.

2. Unbounded folder-index reads

loadActiveFolderPathIndex was called without maxRows at 15 sites, while adjacent code two lines away passed the cap. Rather than paste the constant 15 more times, the cap is now the function's default. Safe because it throws (FolderCollectionLimitExceededError) rather than truncating, the query uses .limit(maxRows + 1) so a workspace exactly at the cap still passes, and folder creation already refuses at the same ceiling. Every domain constant is the identical value — MAX_KNOWLEDGE_FOLDERS_PER_WORKSPACE is literally an alias.

3. Invalid cursors silently restarting pagination

GET /api/v2/tables/{tableId}/rows coerced an undecodable cursor to offset 0 and re-served page 1 — which can make a paging client loop forever. Eight sibling v2 cursor lists already reject; this route was the sole outlier. Extracted decodeOffsetCursor beside the existing decodeSortedCursor (the only two routes using the offset shape). Kept the literal 'Invalid cursor' rather than INVALID_CURSOR_MESSAGE, whose text is sort-mismatch-specific and would be wrong here.

Reverting each fix turns its tests red. type-check · biome · 633 tests · check:api-validation · check:openapi — all pass.

Follow-up left undone: maxRows: MAX_FOLDERS_PER_WORKSPACE is now redundant at ~25 call sites, but removing it means edits far outside this diff and would break tests asserting it explicitly.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@vercel

vercel Bot commented Aug 11, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
docs Ready Ready Preview Aug 11, 2026 11:31pm

Request Review

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@cursor

cursor Bot commented Aug 11, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown

PR Summary

Medium Risk
Changes public pagination behavior for invalid cursors and can fail workflow create/update when a workspace exceeds the folder cap on the folderId path. Dead-code removal itself is low risk.

Overview
Three independent cleanups from the v2 parity audit.

Dead route builder. Deletes unused withPublicApiRouteHandler (and its test) plus ~27 unused ApiEndpoint telemetry labels that no production route passed to rate limiting. Drops the audit-script recognition for that builder; v2 already uses defineV2JsonRoute + v2RateLimits.

Bounded folder-index reads. createWorkflow / updateWorkflow now pass maxRows: MAX_FOLDERS_PER_WORKSPACE on the folderId branch, matching the already-bounded folderPath path. Documents that loadActiveFolderPathIndex keeps maxRows opt-in so over-cap workspaces remain readable.

Invalid cursor rejection. Adds shared decodeOffsetCursor and switches table-rows (and knowledge documents) listing to it. Malformed or non-offset cursors now return 400 instead of coercing to offset 0 and re-serving page one.

Reviewed by Cursor Bugbot for commit 23b7792. Configure here.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

This was referenced Aug 11, 2026
fix(api): stop leaking failed SQL in v1 table 500s and restore the 423 lock field #6569
Merged
fix(skills): only reject a built-in name collision on an actual rename #6570
Merged
@greptile-apps

greptile-apps Bot commented Aug 11, 2026 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR removes an unused public-route wrapper and dead endpoint labels, centralizes strict offset-cursor validation, and narrows folder-index bounds after the earlier review.

  • Keeps omitted folder-index reads unbounded while explicitly bounding selected workflow reads.
  • Rejects malformed offset cursors instead of restarting pagination.
  • Removes unused public API routing code and telemetry labels.

Confidence Score: 4/5

The PR is not yet safe to merge because an accepted over-cap folder state can make workflow updates commit and then return HTTP 413.

The capped fallback folder-index read occurs after updateWorkflowRecord, so workspaces that exceed the unenforced folder ceiling can receive a failure response after the requested workflow mutation has already persisted.

Files Needing Attention: apps/sim/lib/workflows/application/update-workflow.ts

Important Files Changed

Filename Overview
apps/sim/lib/workflows/application/update-workflow.ts Adds bounded folder-index reads, but the fallback read can throw after a workflow update has already persisted.
apps/sim/lib/workflows/application/create-workflow.ts Explicitly bounds the folderId branch's folder-index load.
apps/sim/lib/folders/queries.ts Preserves unbounded behavior when maxRows is omitted and documents the opt-in bound.
apps/sim/app/api/v2/lib/response.ts Adds reusable validation for offset cursors.
apps/sim/app/api/v2/tables/[tableId]/rows/route.ts Uses strict offset-cursor decoding for table-row pagination.
apps/sim/app/api/v1/middleware.ts Removes endpoint labels associated with the deleted unused route builder.

Comments Outside Diff (1)

  1. apps/sim/lib/workflows/application/update-workflow.ts, line 181-185 (link)

    P1 Update commits before folder failure

    If a workspace contains more than 10,000 active workflow folders, a name-, description-, lock-, or policy-only update persists through updateWorkflowRecord, then this capped fallback index read throws and returns HTTP 413. The caller therefore receives a failure even though the requested workflow mutation has already committed.

Reviews (2): Last reviewed commit: "fix(api): reject an undecodable offset c..." | Re-trigger Greptile

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

greptile-apps[bot]
greptile-apps Bot reviewed Aug 11, 2026
View reviewed changes
Comment thread apps/sim/lib/folders/queries.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

@vercel
vercel Bot deployed to Preview August 11, 2026 23:09
View deployment
waleedlatif1 added 3 commits August 11, 2026 16:23
@waleedlatif1
chore(api): remove the unused public API route builder and dead endpo…
aa8f09a
…int labels

`withPublicApiRouteHandler` and 27 `ApiEndpoint` union members landed together
in #5273, but the v2 surface shipped on `defineV2JsonRoute` + `v2RateLimits`
instead. The builder had no production caller — only its own test — and the v2
rate limiter never reads an `ApiEndpoint` label, so those members were never
emitted to telemetry by symbol or by string literal.

Remaining members are exactly the labels a v1 route passes to `checkRateLimit`
or `authenticateRequest`. Drops the now-unreachable `hasZodUsage` branch from
the API validation audit; no ratchet metric moves (route total stays 1093).
@waleedlatif1
fix(folders): bound the workflow folderId-branch path index reads
46f9c2f
`createWorkflow` and `updateWorkflow` each resolve a folder two ways inside one
function. The folderPath branch goes through `resolveWorkflowFolderPath`, which
loads the path index with `maxRows: MAX_FOLDERS_PER_WORKSPACE`; the folderId
branch loaded it with no bound at all, issuing a `SELECT` over every active
folder row in the workspace. In `updateWorkflow` the unbounded read and the
bounded fallback sit thirty lines apart in the same function.

Passes the cap at both sites, matching the read sites that already opt in.
Exceeding it throws `FolderCollectionLimitExceededError` rather than truncating,
because a partial path index resolves real folder paths to `undefined` and
re-roots resources at the workspace root.

`maxRows` deliberately stays opt-in rather than becoming the default. Folder
creation does not refuse at the same ceiling on every path — `POST /api/folders`
goes through the `createFolder` name/parentId variant, which passes no
`maxFolderRows`, so the count guard in `executeCreateFolderAtPath` never runs
and a workspace can already hold more than `MAX_FOLDERS_PER_WORKSPACE` folders.
Defaulting the bound would make every path-index consumer throw for a state the
product allows to exist. Reconciling reader and writer is a separate change with
a user-facing limit, not a chore.
@waleedlatif1
fix(api): reject an undecodable offset cursor on v2 table rows
23b7792
GET /api/v2/tables/{tableId}/rows coerced an undecodable pagination cursor to
offset 0 and re-served page one. A client paging forward reads that as a fresh
first page and can loop over it forever. Every sibling v2 cursor list — logs,
files, workflows, workflow runs, workflow versions, workspace members, tables,
knowledge documents — already rejects with a validation error instead.

Extracts the offset-cursor decode both offset-paginated v2 routes had inlined
into `decodeOffsetCursor`, next to the existing `decodeSortedCursor`, so the
reject-don't-restart rule has one home.
@waleedlatif1
waleedlatif1 force-pushed the fix/v2-billing-status-authz branch from 9667823 to 79a3486 Compare August 11, 2026 23:24
@waleedlatif1
waleedlatif1 force-pushed the chore/v2-dead-code-and-bounds branch from fe432f9 to 23b7792 Compare August 11, 2026 23:25
@waleedlatif1

waleedlatif1 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

@greptile-apps

greptile-apps[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@waleedlatif1

waleedlatif1 commented Aug 11, 2026

Copy link
Copy Markdown
Collaborator Author

@cursor review

cursor[bot] reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

cursor[bot]
cursor Bot reviewed Aug 11, 2026
View reviewed changes

@cursor cursor Bot left a comment

Copy link
Copy Markdown

There was a problem hiding this comment.

Choose a reason for hiding this comment

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

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 23b7792. Configure here.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@vercel
vercel Bot deployed to Preview August 11, 2026 23:31
View deployment
@waleedlatif1
waleedlatif1 changed the base branch from fix/v2-billing-status-authz to improvement/v2-route-standardization August 11, 2026 23:35
@waleedlatif1
waleedlatif1 merged commit 3cab8ef into improvement/v2-route-standardization Aug 11, 2026
5 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@waleedlatif1
waleedlatif1 deleted the chore/v2-dead-code-and-bounds branch August 11, 2026 23:36

This branch was successfully deployed

1 active deployment
Preview — 23b77927 Deployed Aug 11, 2026 by vercel[bot]
View deployment
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@greptile-apps greptile-apps[bot] greptile-apps[bot] left review comments
@cursor cursor[bot] cursor[bot] left review comments

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

1 participant

@waleedlatif1
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.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.