vercel/next.js · error · SerializableError

Error serializing `${path}` returned from `${method}` in "${

Error message

Error serializing `${path}` returned from `${method}` in "${page}".
Reason: `undefined` cannot be serialized as JSON. Please use `null` or omit this value.

What it means

Thrown by isSerializableProps() when a property value anywhere in the props tree is strictly `undefined`. JSON.stringify silently drops undefined values, which would cause the client to receive props missing fields unexpectedly, so Next.js fails fast and asks for null or omission instead.

Source

Thrown at packages/next/src/lib/is-serializable-props.ts:71

  ): true {
    const type = typeof value
    if (
      // `null` can be serialized, but not `undefined`.
      value === null ||
      // n.b. `bigint`, `function`, `symbol`, and `undefined` cannot be
      // serialized.
      //
      // `object` is special-cased below, as it may represent `null`, an Array,
      // a plain object, a class, et al.
      type === 'boolean' ||
      type === 'number' ||
      type === 'string'
    ) {
      return true
    }

    if (type === 'undefined') {
      throw new SerializableError(
        page,
        method,
        path,
        '`undefined` cannot be serialized as JSON. Please use `null` or omit this value.'
      )
    }

    if (isPlainObject(value)) {
      visit(refs, value, path)

      if (
        Object.entries(value).every(([key, nestedValue]) => {
          const nextPath = regexpPlainIdentifier.test(key)
            ? `${path}.${key}`
            : `${path}[${JSON.stringify(key)}]`

          const newRefs = new Map(refs)
          return (

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Coalesce undefined values to null: `value ?? null`.
  2. Strip undefined keys before returning: build the props object with only defined fields, or run a sanitiser that deletes undefined properties.
  3. Provide explicit defaults so fields are always a serializable type (string, number, boolean, null, array, plain object).
  4. If using TypeScript, type the props bag so undefined is not allowed (no optional properties whose absence matters).

Example fix

// before
export async function getStaticProps() {
  const u = await getUser(id)
  return { props: { user: { name: u.name, bio: u.bio } } } // bio may be undefined
}
// after
export async function getStaticProps() {
  const u = await getUser(id)
  return {
    props: { user: { name: u.name, bio: u.bio ?? null } },
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function stripUndefined(obj: unknown): unknown {
  if (Array.isArray(obj)) return obj.map(stripUndefined)
  if (obj && typeof obj === 'object') {
    return Object.fromEntries(
      Object.entries(obj)
        .filter(([, v]) => v !== undefined)
        .map(([k, v]) => [k, stripUndefined(v)])
    )
  }
  return obj
}
// in getStaticProps: return { props: stripUndefined(props) }

Type guard

function hasUndefinedLeaves(v: unknown): boolean {
  if (v === undefined) return true
  if (v && typeof v === 'object') {
    return Object.values(v).some(hasUndefinedLeaves)
  }
  return false
}

Prevention

When it happens

Trigger: During deep traversal, typeof value === 'undefined' for any leaf or nested property of the returned props. Common when a DB field is absent (returns undefined), an optional API response omits a key, or a conditional expression yields undefined.

Common situations: Optional database columns that are null in some rows but undefined in code paths; spreading an object whose keys are conditionally undefined; deserialization that leaves undefined gaps; or default parameters that fall through to undefined.

Related errors


AI-assisted analysis of vercel/next.js@0ae8c72462 (2026-08-06). Data as JSON: /api/errors/d4920c0827421acd. Report an issue: GitHub.