Skip to content

fix(ci): require a default export before treating a file as a route entry - #7028

Merged
waleedlatif1 merged 2 commits into
stagingfrom
fix-boundary-entry-discriminator
Aug 24, 2026
Merged

fix(ci): require a default export before treating a file as a route entry#7028
waleedlatif1 merged 2 commits into
stagingfrom
fix-boundary-entry-discriminator

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Follow-up to #7026. Both points were raised in review there and I merged before reading them, so they land here.

The filename was never the right test

#7026 added error.tsx to the entry filenames, and with it picked up [workspaceId]/components/error/error.tsx — named like a boundary, and not one:

export interface ErrorBoundaryProps {  }
export function ErrorShell() {  }
export function ErrorState() {  }

Named exports only. It is the shared helper the thirteen real boundaries render, and Next would reject it as a boundary for having no default export.

Counting it inflated the coverage number and — the part that would have bitten — recorded a shared component in the graph-weight baseline as though it were a route.

Every convention-composed entry must default-export the thing Next renders, so that is the discriminator now.

Entry count 60 → 59. All thirteen real error.tsx boundaries still walk; only the helper drops out.

Completing the enumeration

Also adds template.tsx and default.tsx. Neither exists under app/workspace today, so this changes nothing right now — but the list claims to cover what Next composes, and leaving two out makes that claim false the day someone adds one. That is the same failure the surrounding TSDoc already warns about: "A hardcoded list goes stale silently."

Verification

✓ tool registry stays out of 59 workspace page/layout graphs
error.tsx entries walked: 13
components/error/error.tsx: not present

Credit

The non-route entry was Cursor's; the missing template.tsx/default.tsx was Greptile's. Both were correct.

…ntry

Follow-up to #7026, which added `error.tsx` to the entry filenames and with it
picked up `[workspaceId]/components/error/error.tsx` — named like a boundary,
and not one. It exports `ErrorShell` and `ErrorState` for the thirteen real
boundaries to use; Next would reject it as a boundary for having no default
export. Counting it inflated the coverage number and would have recorded a
shared component in the graph-weight baseline as though it were a route.

The filename was never the right test. Every convention-composed entry must
default-export the thing Next renders, so that is the discriminator now. Entry
count goes 60 → 59, and all thirteen real `error.tsx` boundaries still walk.

Also adds `template.tsx` and `default.tsx`. Neither exists under
`app/workspace` today, so this changes nothing now — but the enumeration claims
to cover what Next composes, and leaving two out makes that claim false the day
someone adds one.

Both raised in review on #7026 (Cursor and Greptile respectively); I merged
before reading them, so this lands separately.
@vercel

vercel Bot commented Aug 24, 2026

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 24, 2026 3:06am

Request Review

@cursor

cursor Bot commented Aug 24, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
CI-only change to how route entries are enumerated; no runtime, auth, or data-path impact. The regex could miss unusual default-export forms, which would under-count entries rather than ship bad code.

Overview
Tightens how check-tool-registry-boundary.ts discovers Next.js workspace entries so a filename match is no longer enough.

collectEntries now also requires a default export (export default or export { … as default}). That drops the shared [workspaceId]/components/error/error.tsx helper (named like a boundary, no default) from the walk and graph-weight baseline, while the real error.tsx boundaries stay. Entry count goes 60 → 59.

Also enumerates template.tsx and default.tsx so the convention list matches what Next composes. Neither exists under app/workspace today.

Reviewed by Cursor Bugbot for commit c01be22. Configure here.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

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 using high effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit c01be22. Configure here.

Comment thread scripts/check-tool-registry-boundary.ts Outdated
@greptile-apps

greptile-apps Bot commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This follow-up tightens workspace route discovery by requiring a default export and completes the convention-entry filename set.

  • Recognizes direct default exports and default re-export forms, including the previously missed export { default } from syntax.
  • Excludes named-export-only helpers from route graph checks.
  • Adds template.tsx and default.tsx to the discovered entry filenames.

Confidence Score: 5/5

The PR appears safe to merge.

No blocking failure remains; the previously reported omission of export { default } from is fixed at the current head.

Important Files Changed

Filename Overview
scripts/check-tool-registry-boundary.ts Route-entry discovery now requires a recognized default export, covers the previously missed default re-export form, and enumerates two additional Next.js entry filenames.

Reviews (2): Last reviewed commit: "fix(ci): count every form that declares ..." | Re-trigger Greptile

Comment thread scripts/check-tool-registry-boundary.ts Outdated
`export { default } from './page'` is a valid Next entry and the regex required
`as default`, so such an entry would have dropped out of the walk and skipped
both the registry gate and the graph-weight ratchet — silently, which is the
dangerous direction for a discriminator to fail in.

Latent rather than live: the form appears once under `app/workspace`, in a
barrel, not in an entry filename.

Four forms now count — `export default …`, `export { default } from`,
`export { default, … } from`, and `export { X as default }`.
`export { default as X }` still does not: it re-exports another module's default
under a name and leaves this one without one. Verified all ten variants,
including that last distinction.

Raised by both Cursor and Greptile on #7028.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile-apps the score is a commit behind — last reviewed c01be22d1e, head is 376e373ec2. The missed export { default } from form behind the 4/5 is fixed there. Please re-review.

@waleedlatif1
waleedlatif1 merged commit 67fc2ae into staging Aug 24, 2026
29 checks passed
@waleedlatif1
waleedlatif1 deleted the fix-boundary-entry-discriminator branch August 24, 2026 07:49
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