vercel/next.js · error · SerializableError

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

Error message

Error serializing `${path}` returned from `${method}` in "${page}".
Reason: `${type}` cannot be serialized as JSON. Please only return JSON serializable data types.

What it means

Thrown by isSerializableProps() when a value's typeof is one of bigint, symbol, function, or a non-plain object type that is neither null nor an Array. None of these can be expressed in JSON. The message includes the type (and for objects, the Object.prototype.toString tag) so the developer can locate the offending value.

Source

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

        value.every((nestedValue, index) => {
          const newRefs = new Map(refs)
          return isSerializable(newRefs, nestedValue, `${path}[${index}]`)
        })
      ) {
        return true
      }

      throw new SerializableError(
        page,
        method,
        path,
        `invariant: Unknown error encountered in Array.`
      )
    }

    // None of these can be expressed as JSON:
    // const type: "bigint" | "symbol" | "object" | "function"
    throw new SerializableError(
      page,
      method,
      path,
      '`' +
        type +
        '`' +
        (type === 'object'
          ? ` ("${Object.prototype.toString.call(value)}")`
          : '') +
        ' cannot be serialized as JSON. Please only return JSON serializable data types.'
    )
  }

  return isSerializable(new Map(), input, '')
}

View on GitHub (pinned to 0ae8c72462)

Solutions

  1. Convert Dates to ISO strings (date.toISOString()).
  2. Convert bigint to string (id.toString()) or number if safe.
  3. Replace Map/Set with plain objects/arrays; convert Buffer to base64 string.
  4. Strip or serialize class instances via .toJSON()/.toObject() before returning.

Example fix

// before
export async function getStaticProps() {
  const item = await getItem(id)
  return { props: { item: { id: item.id, createdAt: item.createdAt } } }
  // createdAt is a Date, id is bigint -> error
}
// after
export async function getStaticProps() {
  const item = await getItem(id)
  return {
    props: {
      item: { id: String(item.id), createdAt: item.createdAt.toISOString() },
    },
  }
}
Defensive patterns

Strategy: validation

Validate before calling

function toSerializable(v: unknown): unknown {
  if (v instanceof Date) return v.toISOString()
  if (typeof v === 'bigint') return v.toString()
  if (v instanceof Map) return Object.fromEntries(v)
  if (v instanceof Set) return [...v]
  if (v && typeof v === 'object' && typeof (v as any).toJSON === 'function') return (v as any).toJSON()
  if (Array.isArray(v)) return v.map(toSerializable)
  if (v && typeof v === 'object') return Object.fromEntries(Object.entries(v).map(([k,n])=>[k,toSerializable(n)]))
  return v
}
// return { props: toSerializable(props) }

Type guard

function isJsonPrimitive(v: unknown): boolean {
  return v === null || ['boolean','number','string'].includes(typeof v)
}

Prevention

When it happens

Trigger: A leaf or nested value in props is a bigint (e.g. BigInt ID), a Symbol, a function/component reference, or a non-plain object like a Date, Map, Set, RegExp, Error, ArrayBuffer, or class instance that is not caught by isPlainObject.

Common situations: Returning a Date object instead of an ISO string; bigint IDs from a database; passing a function/component reference in props; Map/Set/Buffer from Node APIs; class instances from domain models. Different from [113] which fires at the root; this fires on nested non-serializable values.

Related errors


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