Skip to content

Hotfix: fix /skills count fallback runtime on Convex#376

Merged
steipete merged 1 commit intomainfrom
hotfix/convex-globalstats-fallback
Feb 16, 2026
Merged

Hotfix: fix /skills count fallback runtime on Convex#376
steipete merged 1 commit intomainfrom
hotfix/convex-globalstats-fallback

Conversation

@steipete
Copy link
Collaborator

Follow-up hotfix after re-landing #76.

Issue

skills.countPublicSkills fallback used repeated paginated queries, which Convex disallows inside one function.

Fix

  • Switch fallback counting to a single collect() query in convex/lib/globalStats.ts.
  • Keep type-narrowing explicit in toPublicSkill.
  • Update fallback tests.
  • Regenerate convex/_generated/api.d.ts.

Verification

  • bun run lint
  • bun run test
  • bunx convex deploy -y
  • bunx convex run --deployment-name wry-manatee-359 statsMaintenance:updateGlobalStatsInternal
  • bunx convex run --deployment-name wry-manatee-359 skills:countPublicSkills (returned 7774)

@cursor
Copy link

cursor bot commented Feb 16, 2026

PR Summary

Medium Risk
Touches query logic used for a public-facing count endpoint and changes how all skills are loaded for the fallback path, which could affect performance or correctness at scale, but the change is localized and covered by updated tests.

Overview
Fixes skills.countPublicSkills fallback behavior by changing countPublicSkillsForGlobalStats to use a single collect() query instead of repeated pagination, avoiding Convex runtime restrictions.

Tightens globalStats helper typing by splitting read vs write contexts, adds an explicit null-guard in toPublicSkill, updates the associated unit test mocks to match collect(), and regenerates convex/_generated/api.d.ts to export lib/globalStats.

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

@vercel
Copy link
Contributor

vercel bot commented Feb 16, 2026

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

Project Deployment Actions Updated (UTC)
clawhub Ready Ready Preview, Comment Feb 16, 2026 11:30pm

@steipete steipete merged commit 30ae099 into main Feb 16, 2026
5 checks passed
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 94380d9724

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +56 to +59
const skills = await ctx.db
.query('skills')
.withIndex('by_active_updated', (q) => q.eq('softDeletedAt', undefined))
.collect()

Choose a reason for hiding this comment

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

P2 Badge Avoid full-table collect in public-skill count fallback

When skills.countPublicSkills falls back to countPublicSkillsForGlobalStats (e.g. missing globalStats row/storage), this now loads every active skill in a single .collect() call, which can exceed Convex query result limits for larger datasets and throw instead of returning a count. The repo already treats this as a real constraint for aggregate scans (convex/skills.ts notes using paginated action flow to avoid the 16MB limit), so this fallback can still break /skills in production precisely during cold-start/recovery scenarios.

Useful? React with 👍 / 👎.

Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.

.query('skills')
.withIndex('by_active_updated', (q) => q.eq('softDeletedAt', undefined))
.order('asc')
.paginate({ cursor, numItems: GLOBAL_STATS_PAGE_SIZE })
Copy link

Choose a reason for hiding this comment

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

Collect risks hitting Convex document read limit

Medium Severity

countPublicSkillsForGlobalStats now uses .collect() to load all matching skills into memory. Convex enforces a hard per-function document read limit of 16,384. The current dataset has 7,774 skills — roughly half the cap. When the skills table grows past ~16K non-deleted rows, this will throw a TooManyDocumentsRead error. This affects the countPublicSkills query fallback, adjustGlobalPublicSkillsCount initialization, and the updateGlobalStatsInternal cron job.

Fix in Cursor Fix in Web

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant