claude-code - ✅(Solved) Fix Vercel plugin: false positive "Use named exports" error on page.tsx / layout.tsx files [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#54989Fetched 2026-05-01 05:49:10
View on GitHub
Comments
0
Participants
1
Timeline
4
Reactions
0
Participants
Timeline (top)
labeled ×3cross-referenced ×1

Error Message

The Vercel plugin's posttooluse-validate hook fires a false positive ERROR on every page.tsx, layout.tsx, sitemap.ts, loading.tsx, and not-found.tsx file in a Next.js App Router project. Error message: [ERROR]: Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers Root cause: The validation rule in vercel-functions skill uses the regex pattern export\s+default\s+function which matches ALL files containing a default export. However, this rule is only relevant for route.ts files (API route handlers). Next.js App Router requires default exports for page.tsx, layout.tsx, sitemap.ts, loading.tsx, error.tsx, and not-found.tsx. severity: error

  • Displays a misleading ERROR that the user has to mentally ignore every time severity: error skipIfFilename: 'page.(tsx|jsx)$|layout.(tsx|jsx)$|sitemap.(ts|js)$|loading.(tsx|jsx)$|error.(tsx|jsx)$|not-found.(tsx|jsx)$'

Root Cause

Root cause: The validation rule in vercel-functions skill uses the regex pattern export\s+default\s+function which matches ALL files containing a default export. However, this rule is only relevant for route.ts files (API route handlers). Next.js App Router requires default exports for page.tsx, layout.tsx, sitemap.ts, loading.tsx, error.tsx, and not-found.tsx.

Fix Action

Fixed

PR fix notes

PR #73: vercel-functions: skip default-export rule for App Router pages

Description (problem / solution / changelog)

Fixes the false-positive Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers ERROR that fires on every page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx, sitemap.ts, and template.tsx in a Next.js App Router project.

Refs anthropics/claude-code#54989 (the bug was reported in claude-code, but the validation rule lives here in skills/vercel-functions/SKILL.md lines 25-29).

Problem

The current rule:

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error

matches any default-exported function. Next.js App Router requires default exports for page.tsx, layout.tsx, loading.tsx, error.tsx, not-found.tsx, sitemap.ts, and template.tsx, so the rule fires [ERROR] on every Write/Edit to any of those files. The reporter has a 44-page project where this fires constantly and cannot be suppressed without disabling the entire skill.

Fix

Add a skipIfFileContains regex (the same shape used in skills/routing-middleware/SKILL.md) that suppresses the rule when the file shows strong signals of being an App Router file rather than a route handler:

SignalCatches
'use client' directiveclient components
export const metadata|dynamic|revalidate|fetchCache|runtimeApp Router config exports
export default function …(Page|Layout|Loading|Error|NotFound|Sitemap|Template|Default) (also lower-case sitemap/robots/opengraph/manifest)App Router file conventions
<[A-Z]… (capitalised JSX tag)any JSX-returning page
{ children } destructurelayouts and templates
MetadataRoute.sitemap/robots/manifest helpers
from 'next/(font|image|link|navigation|headers|cookies)'App Router imports

Each of these is overwhelmingly common in App Router pages and overwhelmingly absent from route handlers. A buggy export default function handler inside a route.ts still fires the rule because none of the patterns match.

Why skipIfFileContains and not a new field

The reporter suggested onlyIfFilename / skipIfFilename. Adding a new schema field requires the downstream consumer (claude-code) to honor it, otherwise the field is inert and the false positive remains. skipIfFileContains is already supported and already used by skills/routing-middleware/SKILL.md, so this PR fixes the bug today without coordinating new field support.

Verification

Tested the regex against representative content for each affected file plus the buggy route handler case (Python regex used for portability):

page.tsx (server)                          fires=True  skip=True  -> skipped (correct)
page.tsx (client - 'use client')           fires=True  skip=True  -> skipped (correct)
layout.tsx (RootLayout)                    fires=True  skip=True  -> skipped (correct)
layout.tsx (MarketingLayout)               fires=True  skip=True  -> skipped (correct)
sitemap.ts                                 fires=True  skip=True  -> skipped (correct)
loading.tsx                                fires=True  skip=True  -> skipped (correct)
not-found.tsx                              fires=True  skip=True  -> skipped (correct)
route.ts (BUG: export default fn handler)  fires=True  skip=False -> flagged (correct)
route.ts (BUG: export default with NextResponse) fires=True  skip=False -> flagged (correct)

Plugin-level checks still pass:

$ bun run validate
PASSED with 1 warning(s)

$ bun run build
build:skills — 0 updated, 10 unchanged, 0 errors
build:from-skills — 0 updated, 8 unchanged, 0 errors

Changed files

  • generated/build-from-skills.manifest.json (modified, +1/-1)
  • generated/skill-manifest.json (modified, +3/-2)
  • skills/vercel-functions/SKILL.md (modified, +7/-0)

Code Example

[ERROR]: Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers

---

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error

---

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error
    onlyIfFilename: 'route\.(ts|js)$'

---

skipIfFilename: 'page\.(tsx|jsx)$|layout\.(tsx|jsx)$|sitemap\.(ts|js)$|loading\.(tsx|jsx)$|error\.(tsx|jsx)$|not-found\.(tsx|jsx)$'
RAW_BUFFERClick to expand / collapse

Bug

The Vercel plugin's posttooluse-validate hook fires a false positive ERROR on every page.tsx, layout.tsx, sitemap.ts, loading.tsx, and not-found.tsx file in a Next.js App Router project.

Error message:

[ERROR]: Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers

Root cause: The validation rule in vercel-functions skill uses the regex pattern export\s+default\s+function which matches ALL files containing a default export. However, this rule is only relevant for route.ts files (API route handlers). Next.js App Router requires default exports for page.tsx, layout.tsx, sitemap.ts, loading.tsx, error.tsx, and not-found.tsx.

Location in plugin: skills/vercel-functions/SKILL.md lines 27-29:

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error

Impact

  • Fires on every Write/Edit to any page or layout file
  • Displays a misleading ERROR that the user has to mentally ignore every time
  • Cannot be suppressed without disabling the entire vercel-functions skill
  • Particularly noisy in projects with many pages (my project has 44 page.tsx files)

Suggested fix

Add a filename filter so the rule only fires on route.ts / route.js files:

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error
    onlyIfFilename: 'route\.(ts|js)$'

Or alternatively, use skipIfFilename to exclude known App Router files:

    skipIfFilename: 'page\.(tsx|jsx)$|layout\.(tsx|jsx)$|sitemap\.(ts|js)$|loading\.(tsx|jsx)$|error\.(tsx|jsx)$|not-found\.(tsx|jsx)$'

Environment

  • Claude Code version: 2.1.119
  • Vercel plugin version: 0.32.4 (claude-plugins-official)
  • Framework: Next.js 16 App Router
  • Plugin source: vercel@claude-plugins-official

extent analysis

TL;DR

Update the validate rule in the Vercel plugin's vercel-functions skill to include a filename filter to only apply the rule to route.ts or route.js files.

Guidance

  • Identify the SKILL.md file in the vercel-functions skill and locate the validate rule on lines 27-29.
  • Update the validate rule to include either an onlyIfFilename or skipIfFilename condition to filter out non-route files.
  • Use the suggested onlyIfFilename pattern route\.(ts|js)$ to only apply the rule to route.ts or route.js files.
  • Alternatively, use the suggested skipIfFilename pattern to exclude known App Router files.

Example

validate:
  -
    pattern: export\s+default\s+function
    message: 'Use named exports (GET, POST, PUT, DELETE) instead of default export for route handlers'
    severity: error
    onlyIfFilename: 'route\.(ts|js)$'

Notes

This fix assumes that the onlyIfFilename or skipIfFilename conditions are supported by the Vercel plugin's vercel-functions skill.

Recommendation

Apply the workaround by updating the validate rule with the suggested onlyIfFilename or skipIfFilename condition, as this will prevent the false positive errors without disabling the entire vercel-functions skill.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING