affaan-m/ECC · error

VALIDATION_ERROR

VALIDATION_ERROR

Error message

Request validation failed

What it means

This is the ZodError branch of the handleApiError helper shown in the error-handling skill: when a Next.js route validates its request body with a Zod schema and parsing fails, the handler returns HTTP 422 with code VALIDATION_ERROR and a details array mapping each failing field path to its message. It exists so clients get actionable, field-level feedback instead of a generic 400.

Source

Thrown at skills/error-handling/SKILL.md:138

  if (error instanceof AppError) {
    return NextResponse.json(
      {
        error: {
          code: error.code,
          message: error.message,
          ...(error.details ? { details: error.details } : {}),
        },
      },
      { status: error.statusCode },
    )
  }

  // Zod validation error
  if (error instanceof z.ZodError) {
    return NextResponse.json(
      {
        error: {
          code: 'VALIDATION_ERROR',
          message: 'Request validation failed',
          details: error.issues.map(i => ({
            field: i.path.join('.'),
            message: i.message,
          })),
        },
      },
      { status: 422 },
    )
  }

  // Unexpected error — log details, return generic message
  console.error('Unexpected error:', error)
  return NextResponse.json(
    { error: { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' } },
    { status: 500 },
  )
}

View on GitHub (pinned to d8409a4b08)

Solutions

  1. Read response.error.details[] — each entry names the exact field path and the failing constraint; fix those fields in the request payload
  2. Compare the payload against the route's Zod schema (it is the source of truth for the contract)
  3. If you own the API and just added the field, make it optional or give it a default so older clients keep working
  4. Validate on the client with the same (shared) schema before sending to fail early with better UX

Example fix

// before - client sends body missing a required field
await fetch('/api/users', { method: 'POST', body: JSON.stringify({ email: 'a@b.co' }) })
// -> 422 { code: 'VALIDATION_ERROR', details: [{ field: 'name', message: 'Required' }] }

// after
await fetch('/api/users', { method: 'POST', body: JSON.stringify({ email: 'a@b.co', name: 'Ada' }) })
Defensive patterns

Strategy: validation

Validate before calling

// Server-side: use safeParse and branch before it can throw
const parsed = CreateUserSchema.safeParse(await req.json())
if (!parsed.success) {
  return NextResponse.json(
    { error: { code: 'VALIDATION_ERROR', message: 'Request validation failed', details: parsed.error.issues } },
    { status: 422 },
  )
}
// parsed.data is now fully typed for the handler

Type guard

const isZodError = (e: unknown): e is z.ZodError => e instanceof z.ZodError

Try / catch

try {
  await handler(req)
} catch (error) {
  if (error instanceof z.ZodError) {
    // 422 with field-level details from error.issues — never rethrow raw
    return respond422(error.issues.map(i => ({ field: i.path.join('.'), message: i.message })))
  }
  throw error // let the generic 500 branch log it

Prevention

When it happens

Trigger: POSTing a body that fails the route's Zod schema: missing required field, wrong type (string where number expected), invalid email format, string shorter than a min() constraint, or a nested object whose sub-field fails (reported as dotted paths like 'address.street').

Common situations: Frontend and backend schema drift after a new required field was added server-side; enum value typo from a hand-written curl; JSON key casing mismatch (createdAt vs created_at); empty string sent where min(1) applies; API consumer built against an older version of the contract.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of affaan-m/ECC@d8409a4b08 (2026-08-26). Data as JSON: /api/errors/6a754ef71b37db3e. Report an issue: GitHub.