agentsclimarketplace

Debug frontend

Skill yerdaulet-damir/vibe-coding-rules/.claude/skills/debug-frontend

54 production architecture rules for vibe coding with Claude Code & Cursor. Drop-in CLAUDE.md, .cursor/rules, and .claude/skills for FastAPI, Next.js 15, and Go 1.22+ — turn AI-assisted coding from prototype hack to production.

Install
npx -y skills add yerdaulet-damir/vibe-coding-rules --skill debug-frontend

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Systematic 5-step debugging flow for Next.js 15 + React 19 + TypeScript apps. Load when a UI bug is reported, hydration error appears, Server Action returns wrong data, or cache invalidation fails. Forces layer isolation (server vs client, action vs component, cache vs render) before touching code — prevents "fix here, break there" cascades.

SKILL.md

6.1 KB, as published. Nobody here has run it

debug-frontend

Stop. Do not edit any file yet. Work through these 5 steps in order.


Step 1 — Locate the layer

Next.js bugs almost always live in one of 5 layers. Identify which one before touching code.

SymptomLikely layerFirst grep
500 / runtime error in browserClient componentgrep -rn "'use client'" src/features/<domain>/components/
Hydration mismatchServer vs client divergencegrep -rn "Date()|Math.random|window\." src/features/<domain>/
Wrong data after mutationCache invalidationgrep -rn "revalidateTag|revalidatePath" src/features/<domain>/actions.ts
Server Action returns { error: ... } unexpectedlyValidation or repogrep -n "safeParse|throw" src/features/<domain>/actions.ts
Type error / weird undefinedSchema / typesgrep -rn "z\.infer|as any|@ts-ignore" src/features/<domain>/
Slow page / waterfallData fetch shapegrep -n "await " src/app/<route>/page.tsx (count sequential awaits)

Pick one layer. Do not touch any other layer in this debug pass.


Step 2 — Check the 5 most common Next.js antipatterns

These cause the majority of vibe-coded bugs. Grep for each:

# Antipattern 1: 'use client' on a page or layout (forces 100% client tree)
grep -rn "'use client'" src/app/ | grep -E "(page|layout)\.tsx"

# Antipattern 2: useEffect for data fetching (race conditions, no Suspense)
grep -rn "useEffect.*fetch\|useEffect.*async" src/features/

# Antipattern 3: revalidateTag with magic string (typo = silent miss)
grep -rn "revalidateTag(['\"]" src/  # should find nothing — all should use tags.X()

# Antipattern 4: throw for business errors (breaks errors-as-values)
grep -rn "throw new Error" src/features/*/actions.ts

# Antipattern 5: drizzle-orm leaked outside repository.ts
grep -rn "from 'drizzle-orm" src/features/*/components/ src/features/*/actions.ts
ResultRoot causePrinciple
'use client' on page/layoutWhole tree client-rendered, no RSC benefitsC4
useEffect + fetchRace conditions, waterfall, hydration mismatchC9 / D2
Magic-string revalidateTagCache miss in production due to typoD1
throw in Server ActionClient gets generic error, can't show field hintC5
drizzle-orm in componentHexagonal boundary brokenB1 / D6

Step 3 — Reproduce the bug deterministically

Before changing code, prove you can trigger it on demand.

For a UI bug: narrow the user flow:

1. Visit /users
2. Click "Edit" on user '[email protected]'
3. Submit form with empty name
4. EXPECTED: error shown next to Name field
5. ACTUAL: page reloads with stale data

For a Server Action bug: call the action in isolation:

// scratch test
const result = await createUser({ email: '', name: '' });
console.log(result);  // expected: { success: false, error: 'Invalid input' }

For a cache invalidation bug: check both sides:

# 1. Is the read tagged?
grep -A2 "fetch.*users" src/features/users/  # look for next: { tags: [...] }

# 2. Is the write invalidating the same tag?
grep -A3 "revalidateTag" src/features/users/actions.ts

If the read uses tags.user(id) but the write only invalidates tags.userList() — there's your bug.


Step 4 — Fix in the correct layer

Minimum change. Do not refactor unrelated code.

LayerWhere to fix
Server Component bugsrc/features/<domain>/components/<Feature>Page.tsx
Client Component bugsrc/features/<domain>/components/<Leaf>.tsx
Mutation bugsrc/features/<domain>/actions.ts
Validation bugsrc/features/<domain>/schema.ts
Data access bugsrc/features/<domain>/repository.ts
Cache misssrc/lib/cache/tags.ts + relevant action

Hydration mismatches specifically: add suppressHydrationWarning only as a last resort — first try moving the non-deterministic code (Date, random, window) to a client useEffect for initial render or to a server-only computation.


Step 5 — Verify

# Type check
pnpm typecheck

# Lint
pnpm lint

# Run the failing scenario again — must succeed now
pnpm dev
# (manually walk through the reproduction steps from Step 3)

Then run the antipattern greps from Step 2 again. You must not have introduced any new violation while fixing.


Common error → root cause table

Error / SymptomWhere to look firstLikely cause
Hydration failed because the initial UI does not matchClient componentDate() or Math.random() in render
useActionState is undefinedImportsMissing 'use client' directive
Form submits but data doesn't refreshServer ActionMissing revalidateTag or wrong tag
Cannot read properties of undefined (reading 'X') after fetchSchemaAPI response doesn't match Zod schema; safeParse returned error and was ignored
500 on Server Actionactions.tsthrow for a business error instead of returning { success: false }
Page is slow but data loads fast in isolationPage structureSequential awaits creating waterfall (Principle D3)
Shows stale data after router.refresh()CacheTag mismatch between fetch and invalidate
dynamic = 'force-dynamic' but PPR enabled warningnext.configEither remove force-dynamic or remove PPR for that route
Bundle size grewComponent tree'use client' on a page pulled the whole tree client-side

Verification

The skill was applied correctly when:

  • A reproducible scenario exists (Step 3)
  • Fix touches exactly one layer
  • All 5 antipattern greps still come up clean
  • pnpm typecheck && pnpm lint exits 0
  • The reproduction scenario now passes

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.