← ClaudeAtlas

nextjs-server-action-validationlisted

Use when writing a Next.js Server Action that accepts user-submitted form data, mutation parameters, or any client-originated input. Every Server Action is a public HTTP endpoint regardless of how it is called — validate with Zod and check authentication as the first two operations before touching the database. Do NOT use for GET route handlers or Server Components that fetch data (those have no user-supplied input); do NOT use for Stripe webhook handlers (use stripe-webhook-signature-verification instead).
jacob-balslev/skill-graph · ★ 0 · API & Backend · score 68
Install: claude install-skill jacob-balslev/skill-graph
# Next.js Server Action Validation ## Coverage - The public endpoint reality — `'use server'` functions are exposed as POST endpoints that any HTTP client can call directly; the Next.js call graph is not a security boundary - Validation order — auth check BEFORE Zod parse, Zod parse BEFORE database access; any other order produces an exploitable window - Zod schema design for actions — using `.safeParse()` over `.parse()` to return structured errors rather than throwing; returning `{ error: ... }` shapes that the calling Client Component can render - Org-scoping after authentication — verifying that `input.orgId` matches the session's org, not just that the user is logged in - Error surface control — how `try/catch` around database calls prevents internal errors from propagating to the client response ## Philosophy Server Actions are a convenience feature that makes form submission feel like a function call. That convenience obscures a critical fact: the action is a public HTTP POST endpoint. A developer who writes `const { data } = await myAction(formData)` in a Client Component is writing what looks like a local function call, but the runtime sends an HTTP request that any script can replicate. Skipping auth or validation because "it's called from our own UI" is the same reasoning that made `getServerSideProps` data-fetching functions leaky in the Pages Router — the server boundary does not restrict callers. ## Standard Action Pattern ```typescript "use server"; impor