{"record":{"id":"ba8cf2b8415769b1","repo":"gatsbyjs/gatsby","slug":"slice-slicename-was-passed-props-that-are-not","errorCode":null,"errorMessage":"Slice \"${sliceName}\" was passed props that are not serializable (${errors}).","messagePattern":"Slice \"(.+?)\" was passed props that are not serializable \\((.+?)\\)\\.","errorType":"validation","errorClass":"SlicePropsError","httpStatus":null,"severity":"error","filePath":"packages/gatsby/cache-dir/slice.js","lineNumber":23,"sourceCode":"import { InlineSlice } from \"./slice/inline-slice\"\nimport { SlicesContext } from \"./slice/context\"\n\nexport function Slice(props) {\n  if (process.env.GATSBY_SLICES) {\n    // we use sliceName internally, so remap alias to sliceName\n    const internalProps = {\n      ...props,\n      sliceName: props.alias,\n    }\n    delete internalProps.alias\n    delete internalProps.__renderedByLocation\n\n    const slicesContext = useContext(SlicesContext)\n\n    // validate props\n    const propErrors = validateSliceProps(props)\n    if (Object.keys(propErrors).length) {\n      throw new SlicePropsError(\n        slicesContext.renderEnvironment === `browser`,\n        internalProps.sliceName,\n        propErrors,\n        props.__renderedByLocation\n      )\n    }\n\n    if (slicesContext.renderEnvironment === `server`) {\n      return <ServerSlice {...internalProps} />\n    } else if (slicesContext.renderEnvironment === `browser`) {\n      // in the browser, we'll just render the component as is\n      return <InlineSlice {...internalProps} />\n    } else if (\n      slicesContext.renderEnvironment === `engines` ||\n      slicesContext.renderEnvironment === `dev-ssr`\n    ) {\n      // if we're in SSR, we'll just render the component as is\n      return <InlineSlice {...internalProps} />","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/cache-dir/slice.js#L5-L41","documentation":"Thrown as a SlicePropsError when the <Slice> component receives props that are not serializable. Gatsby Slices render components in a separate pass and pass data via serialization (especially in SSR/DSG), so all props must be JSON-serializable. validateSliceProps recursively checks each prop; if any value is a function, or contains a function deep in its structure, the error lists all offending prop paths.","triggerScenarios":"A <Slice alias='header' /> call passes a function as a prop (e.g. onClick, render prop), an object containing methods, a React element (which has internal functions), or a class instance. validateSliceProps traverses the entire prop tree and collects all non-serializable paths before throwing.","commonSituations":"Passing event handlers (onClick, onChange) to a Slice, passing a React component or element as a prop, passing a Date or Map/Set object (not plain JSON-serializable), or spreading a large props object that accidentally includes functions.","solutions":["Remove all function-typed props from <Slice> — move event handlers into the Slice component itself or use a context/callback approach inside the Slice.","Ensure only plain objects, arrays, strings, numbers, booleans, and null are passed as Slice props.","If you need to pass complex data, serialize it first (e.g. Date.toISOString()).","Review the error message: it lists each non-serializable prop path (e.g. 'onClick', 'config.render')."],"exampleFix":"// before — passing a function to a Slice\n<Slice alias=\"header\" onMenuClick={() => setOpen(true)} />\n\n// after — move interactivity inside the Slice component\n// In the slice component itself:\nexport default function Header() {\n  const [open, setOpen] = useState(false)\n  return <nav onClick={() => setOpen(!open)}>...</nav>\n}\n// Usage: <Slice alias=\"header\" />  // no function props","handlingStrategy":"validation","validationCode":"// Validate Slice props are serializable before passing\nfunction isSerializable(value, seen = new WeakSet()) {\n  if (value === null || value === undefined) return true\n  const t = typeof value\n  if (t === 'string' || t === 'number' || t === 'boolean') return true\n  if (t === 'function') return false\n  if (t === 'object') {\n    if (seen.has(value)) return true // circular ref, treat as OK for this check\n    seen.add(value)\n    return Object.values(value).every(v => isSerializable(v, seen))\n  }\n  return false\n}\n\n// Usage before rendering:\nif (!isSerializable(sliceProps)) {\n  console.error('Slice props contain non-serializable values')\n}","typeGuard":"// Type guard: ensure Slice props are plain serializable data\ntype Serializable = string | number | boolean | null | Serializable[] | { [k: string]: Serializable }\n\nfunction isSerializableProps(props: unknown): props is Serializable {\n  if (props === null || props === undefined) return true\n  const t = typeof props\n  if (t === 'string' || t === 'number' || t === 'boolean') return true\n  if (t === 'function') return false\n  if (Array.isArray(props)) return props.every(isSerializableProps)\n  if (t === 'object') return Object.values(props).every(isSerializableProps)\n  return false\n}","tryCatchPattern":null,"preventionTips":["Never pass functions, class instances, React elements, or Symbols as Slice props.","Keep Slice props limited to plain JSON-serializable data (strings, numbers, booleans, arrays, plain objects).","Move interactivity (event handlers, state) inside the Slice component itself.","Serialize complex values (e.g. Date -> ISO string) before passing."],"tags":["slices","serialization","react","props","ssr"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}