gatsbyjs/gatsby · error · SlicePropsError
Slice "${sliceName}" was passed props that are not serializa
Error message
Slice "${sliceName}" was passed props that are not serializable (${errors}). What it means
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.
Source
Thrown at packages/gatsby/cache-dir/slice.js:23
import { InlineSlice } from "./slice/inline-slice"
import { SlicesContext } from "./slice/context"
export function Slice(props) {
if (process.env.GATSBY_SLICES) {
// we use sliceName internally, so remap alias to sliceName
const internalProps = {
...props,
sliceName: props.alias,
}
delete internalProps.alias
delete internalProps.__renderedByLocation
const slicesContext = useContext(SlicesContext)
// validate props
const propErrors = validateSliceProps(props)
if (Object.keys(propErrors).length) {
throw new SlicePropsError(
slicesContext.renderEnvironment === `browser`,
internalProps.sliceName,
propErrors,
props.__renderedByLocation
)
}
if (slicesContext.renderEnvironment === `server`) {
return <ServerSlice {...internalProps} />
} else if (slicesContext.renderEnvironment === `browser`) {
// in the browser, we'll just render the component as is
return <InlineSlice {...internalProps} />
} else if (
slicesContext.renderEnvironment === `engines` ||
slicesContext.renderEnvironment === `dev-ssr`
) {
// if we're in SSR, we'll just render the component as is
return <InlineSlice {...internalProps} />View on GitHub (pinned to 8b06340921)
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').
Example fix
// before — passing a function to a Slice
<Slice alias="header" onMenuClick={() => setOpen(true)} />
// after — move interactivity inside the Slice component
// In the slice component itself:
export default function Header() {
const [open, setOpen] = useState(false)
return <nav onClick={() => setOpen(!open)}>...</nav>
}
// Usage: <Slice alias="header" /> // no function props Defensive patterns
Strategy: validation
Validate before calling
// Validate Slice props are serializable before passing
function isSerializable(value, seen = new WeakSet()) {
if (value === null || value === undefined) return true
const t = typeof value
if (t === 'string' || t === 'number' || t === 'boolean') return true
if (t === 'function') return false
if (t === 'object') {
if (seen.has(value)) return true // circular ref, treat as OK for this check
seen.add(value)
return Object.values(value).every(v => isSerializable(v, seen))
}
return false
}
// Usage before rendering:
if (!isSerializable(sliceProps)) {
console.error('Slice props contain non-serializable values')
} Type guard
// Type guard: ensure Slice props are plain serializable data
type Serializable = string | number | boolean | null | Serializable[] | { [k: string]: Serializable }
function isSerializableProps(props: unknown): props is Serializable {
if (props === null || props === undefined) return true
const t = typeof props
if (t === 'string' || t === 'number' || t === 'boolean') return true
if (t === 'function') return false
if (Array.isArray(props)) return props.every(isSerializableProps)
if (t === 'object') return Object.values(props).every(isSerializableProps)
return false
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- The prop `fluid` or `fixed` is marked as required in `${comp
- Nested slices are not supported.${additionalContextMessage}
- Slice context "${slicesContext.renderEnvironment}" is not su
- Slice "${concreteSliceName}" for "${sliceName}" slot not fou
- Expected "Head" export to be a function got "${typeof head}"
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/ba8cf2b8415769b1.
Report an issue: GitHub.