{"record":{"id":"026fb63dac57ce15","repo":"withastro/astro","slug":"the-passed-value-can-t-be-serialized","errorCode":null,"errorMessage":"The passed value can't be serialized.","messagePattern":"The passed value can't be serialized\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/astro/src/core/middleware/index.ts","lineNumber":226,"sourceCode":"\treturn proto === baseProto;\n}\n\n/**\n * It attempts to serialize `value` and return it as a string.\n *\n * ## Errors\n *  If the `value` is not serializable if the function will throw a runtime error.\n *\n * Something is **not serializable** when it contains properties/values like functions, `Map`, `Set`, `Date`,\n * and other types that can't be made a string.\n *\n * @param value\n */\nfunction trySerializeLocals(value: unknown) {\n\tif (isLocalsSerializable(value)) {\n\t\treturn JSON.stringify(value);\n\t} else {\n\t\tthrow new Error(\"The passed value can't be serialized.\");\n\t}\n}\n\n// NOTE: this export must export only the functions that will be exposed to user-land as officials APIs\nexport { createContext, sequence, trySerializeLocals };\nexport { defineMiddleware } from './defineMiddleware.js';\n","sourceCodeStart":208,"sourceCodeEnd":233,"githubUrl":"https://github.com/withastro/astro/blob/e294953aa8aadd98d5be92e60a03037b05dbdfd4/packages/astro/src/core/middleware/index.ts#L208-L233","documentation":"trySerializeLocals is the official helper adapters (Netlify, Vercel) use to pack locals into the x-astro-locals header when forwarding a request from edge middleware to the serverless function. It JSON.stringify's the value only if every part passes isLocalsSerializable; functions, Dates, Maps, Sets, class instances and other non-JSON values fail, and it throws a plain Error ('The passed value can't be serialized.').","triggerScenarios":"Edge middleware stores non-JSON values in context.locals right before the platform bridge serializes them: locals.visit = new Date(), locals.user = new User(...) (class instance), a function reference, a Map/Set cache, or undefined-bearing structures.","commonSituations":"Geolocation or auth SDK objects placed in locals at the edge; copying function-oriented session objects into locals; a codebase that worked on adapters without edge middleware failing once edge middleware is enabled.","solutions":["Store only plain JSON values in edge-middleware locals (strings, numbers, booleans, arrays, plain objects)","Convert before storing: dates to ISO strings, class instances to plain data (user.toJSON() or manual pick)","Keep just an identifier in locals (session id) and load the rich object server-side in the function","Strip unserializable keys before the handoff instead of letting the adapter serialize everything"],"exampleFix":"// before (edge middleware)\ncontext.locals.session = session; // class instance with methods\n\n// after\ncontext.locals.sessionId = session.id;","handlingStrategy":"type-guard","validationCode":"function assertLocalsSerializable(locals: App.Locals): void {\n  for (const [key, value] of Object.entries(locals)) {\n    if (!isSerializableValue(value)) {\n      throw new TypeError(`locals.${key} is not JSON-serializable; store an identifier instead`);\n    }\n  }\n}\n// call before storing rich objects in edge middleware locals","typeGuard":"function isSerializableValue(value: unknown): boolean {\n  if (value === null) return true;\n  const type = typeof value;\n  if (type === 'string' || type === 'number' || type === 'boolean') return true;\n  if (type !== 'object') return false; // functions, symbols, undefined, bigint\n  if (Array.isArray(value)) return value.every(isSerializableValue);\n  if (value instanceof Date || value instanceof Map || value instanceof Set) return false;\n  return Object.values(value).every(isSerializableValue);\n}","tryCatchPattern":null,"preventionTips":["Keep edge-middleware locals to plain JSON: primitives, arrays, plain objects","Store IDs, not instances (sessionId instead of a session class); hydrate server-side","Convert Dates to ISO strings before storing"],"tags":["locals","serialization","edge-middleware","json","adapter"],"backgroundTag":"request-state-not-serializable","analyzedSha":"e294953aa8aadd98d5be92e60a03037b05dbdfd4","analyzedAt":"2026-08-18T18:48:03.901Z","contentChangedAt":"2026-08-18T18:48:03.901Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}