{"record":{"id":"f1a5cc20d799eee6","repo":"vercel/next.js","slug":"error-serializing-props-returned-from-method","errorCode":null,"errorMessage":"Error serializing props returned from `${method}` in \"${page}\".\nReason: Props must be returned as a plain object from ${method}: `{ props: { ... } }` (received: `${getObjectClassLabel(input)}`).","messagePattern":"Error serializing props returned from `(.+?)` in \"(.+?)\"\\.\nReason: Props must be returned as a plain object from (.+?): `(.+?) \\}` \\(received: `(.+?)`\\)\\.","errorType":"exception","errorClass":"SerializableError","httpStatus":null,"severity":"error","filePath":"packages/next/src/lib/is-serializable-props.ts","lineNumber":24,"sourceCode":"const regexpPlainIdentifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/\n\nexport class SerializableError extends Error {\n  constructor(page: string, method: string, path: string, message: string) {\n    super(\n      path\n        ? `Error serializing \\`${path}\\` returned from \\`${method}\\` in \"${page}\".\\nReason: ${message}`\n        : `Error serializing props returned from \\`${method}\\` in \"${page}\".\\nReason: ${message}`\n    )\n  }\n}\n\nexport function isSerializableProps(\n  page: string,\n  method: string,\n  input: any\n): true {\n  if (!isPlainObject(input)) {\n    throw new SerializableError(\n      page,\n      method,\n      '',\n      `Props must be returned as a plain object from ${method}: \\`{ props: { ... } }\\` (received: \\`${getObjectClassLabel(\n        input\n      )}\\`).`\n    )\n  }\n\n  function visit(visited: Map<any, string>, value: any, path: string) {\n    if (visited.has(value)) {\n      throw new SerializableError(\n        page,\n        method,\n        path,\n        `Circular references cannot be expressed in JSON (references: \\`${\n          visited.get(value) || '(self)'\n        }\\`).`","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/vercel/next.js/blob/0ae8c72462952df163f1b1e0726641bc5b40dc93/packages/next/src/lib/is-serializable-props.ts#L6-L42","documentation":"Thrown by isSerializableProps() when the value returned from getStaticProps/getServerSideProps (or getInitialProps) is not a plain Object. The framework requires `{ props: { ... } }` where the props bag is a plain object literal; class instances, arrays, Maps, Dates, or wrapped values fail isPlainObject and report the detected class label.","triggerScenarios":"A data-fetching function returns something other than a plain object as props — e.g. returns an array directly, a class instance, a Map, a React element, or forgets the props wrapper. The check runs after the function resolves during build/prerender.","commonSituations":"Returning a Mongoose document or ORM model instance without `.toObject()`/`.toJSON()`; returning a Date or Map in props; forgetting `{ props: ... }` and returning the data directly; or a serializer that yields a class-typed result.","solutions":["Ensure the return shape is exactly `{ props: { ... } }` with a plain object literal as props.","Call .toObject()/.toJSON()/JSON.parse(JSON.stringify(x)) on ORM/model instances before returning them.","Convert Dates to ISO strings and Maps to plain objects in the props mapping.","If returning arrays, wrap them: `{ props: { items: [...] } }`."],"exampleFix":"// before\nexport async function getStaticProps() {\n  const user = await User.findById(id) // Mongoose document\n  return { props: { user } } // user is a class instance -> error\n}\n// after\nexport async function getStaticProps() {\n  const user = await User.findById(id).lean()\n  return { props: { user: JSON.parse(JSON.stringify(user)) } }\n}","handlingStrategy":"validation","validationCode":"function isPlainSerializableProps(x: unknown): x is Record<string, unknown> {\n  return typeof x === 'object' && x !== null &&\n    Object.getPrototypeOf(x) === Object.prototype || Object.getPrototypeOf(x) === null\n}\n// in getStaticProps:\nif (!isPlainSerializableProps(props)) throw new Error('props must be a plain object')\nreturn { props }","typeGuard":"function isPlainObject(v: unknown): v is Record<string, unknown> {\n  if (typeof v !== 'object' || v === null) return false\n  const proto = Object.getPrototypeOf(v)\n  return proto === Object.prototype || proto === null\n}","tryCatchPattern":null,"preventionTips":["Always return `{ props: { ... } }` with object-literal props.","Call .lean()/.toObject()/.toJSON() on ORM models before returning.","Run a dev-time serialize check (Next.js does this automatically during build).","Avoid spreading class instances into props."],"tags":["serialization","getstaticprops","getserversideprops","build","data-fetching"],"analyzedSha":"0ae8c72462952df163f1b1e0726641bc5b40dc93","analyzedAt":"2026-08-06T19:44:29.143Z","schemaVersion":2},"datasetVersion":"2026-08-07T02:17:10.218Z"}