Validation & Error Handling in Server Actions
Build robust Server Actions by validating input with Zod, returning structured error states, and surfacing them in your forms with useActionState.
Validation & Error Handling in Server Actions is a free Next.js 15 Fullstack (App Router + Server Actions) lesson on CoddyKit — lesson 3 of 3. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Next.js 15 Fullstack (App Router + Server Actions) learning path, one of 3 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Why Validate Server Actions?
Server Actions receive data straight from the client, which can never be trusted. Validation guards against malformed input, injection, and broken business rules before anything touches your database.
Reading FormData
A Server Action bound to a form receives a FormData object. You read fields by name, but every value arrives as a string.
'use server';
export async function createPost(formData: FormData) {
const title = formData.get('title');
const views = formData.get('views');
}Defining a Zod Schema
Zod declares the shape and rules of your data. coerce converts string form values into the right types automatically.
import { z } from 'zod';
const PostSchema = z.object({
title: z.string().min(3, 'Title too short'),
views: z.coerce.number().int().min(0)
});Safe Parsing
Use safeParse instead of parse so validation failures return a result object rather than throwing. Inspect success to branch.
const parsed = PostSchema.safeParse({
title: formData.get('title'),
views: formData.get('views')
});
if (!parsed.success) {
// handle errors
}Returning a Structured Error State
Rather than throwing, return an object describing what went wrong. Field-level messages let the UI show errors next to the right input.
if (!parsed.success) {
return {
errors: parsed.error.flatten().fieldErrors,
message: 'Validation failed'
};
}Wiring useActionState
On the client, useActionState tracks the value your action returns. It gives you the latest state and a wrapped action to pass to the form.
'use client';
const [state, formAction] = useActionState(createPost, { errors: {} });Displaying Field Errors
Render messages from state.errors beneath each field so users see exactly what to fix.
<input name="title" />
{state.errors?.title && (
<p className="error">{state.errors.title[0]}</p>
)}Catching Unexpected Errors
Validation handles bad input, but database or network calls can still fail. Wrap them in try/catch and return a friendly message instead of leaking internals.
try {
await prisma.post.create({ data: parsed.data });
} catch (e) {
return { message: 'Database error. Please try again.' };
}Revalidating on Success
After a successful write, call revalidatePath so cached pages refetch and the new data appears immediately.
import { revalidatePath } from 'next/cache';
revalidatePath('/posts');
return { message: 'Post created!' };Never Trust the Client
Client-side validation improves UX but can be bypassed. Always re-validate on the server. The Server Action is your real security boundary.
Best Practices
Robust actions follow a pattern:
- Validate with Zod safeParse
- Return structured field errors
- Surface them with useActionState
- Wrap side effects in try/catch
- Revalidate on success
Quick Check
Test your validation knowledge.
Recap
You hardened your Server Actions:
- Validate
FormDatawith a Zod schema andsafeParse - Return structured
errorsand amessage - Track them with
useActionStateand render per field - Catch runtime failures and revalidate on success
Your forms now fail gracefully and stay secure.
Frequently asked questions
Is the “Validation & Error Handling in Server Actions” lesson free?
Yes — the full text of “Validation & Error Handling in Server Actions” is free to read here on the web, and the Next.js 15 Fullstack (App Router + Server Actions) course includes 3 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Next.js 15 Fullstack (App Router + Server Actions) course, upgrade to CoddyKit PRO.
What will I learn in “Validation & Error Handling in Server Actions”?
Build robust Server Actions by validating input with Zod, returning structured error states, and surfacing them in your forms with useActionState. You practise Next.js 15 Fullstack (App Router + Server Actions) with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Next.js 15 Fullstack (App Router + Server Actions)?
No prior experience is required. Next.js 15 Fullstack (App Router + Server Actions) on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 3, so you can start here or from the beginning and move at your own pace.
How long does the “Validation & Error Handling in Server Actions” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Next.js 15 Fullstack (App Router + Server Actions) lesson?
Yes. Every Next.js 15 Fullstack (App Router + Server Actions) lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Optimistic UI Updates
- File Uploads with Actions
- Validation & Error Handling in Server Actions