Forms Required
Check every field on the server too
Validate every field on the server with the same rules the form uses, and treat the browser's checks as a convenience only.
How to do it
Write the rules once, in a schema both sides can read. Examples are Zod or Valibot shared between a TypeScript front and back, or a JSON Schema or OpenAPI file that generates both. A Pydantic model on the server can publish JSON Schema for the form. The server answers bad input with 422 and every failing field.
Example
import { z } from 'zod';
export const InvoiceInput = z.object({
customerEmail: z.email(),
amountMinor: z.int().positive(),
dueDate: z.iso.date(),
});
from datetime import date
from pydantic import BaseModel, EmailStr, PositiveInt
class InvoiceInput(BaseModel):
customer_email: EmailStr
amount_minor: PositiveInt
due_date: date
How to check
Send each form's request with a tool such as curl, with one invalid field at a time and no browser. Every request gets 422 and names the field.
For agents: if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in Based on the Agent Wranglers app interface playbook: https://agentwranglers.se/playbook/app-ui/forms/server-side-validation.