gatsbyjs/gatsby · error

${REPORTER_PREFIX} Error serializing pages

Error message

${REPORTER_PREFIX} Error serializing pages

What it means

In gatsby-plugin-sitemap's onPostBuild (gatsby-node.js:67-78), the plugin iterates over filteredPages and calls serialize(page, { resolvePagePath }) for each. If serialize throws synchronously or its promise rejects, reporter.panic fires with the error. serialize is expected to return an object containing at least a 'url' property for each page.

Source

Thrown at packages/gatsby-plugin-sitemap/src/gatsby-node.js:77

  messages.forEach(message => reporter.verbose(message))

  reporter.verbose(
    `${REPORTER_PREFIX} ${filteredPages.length} pages remain after filtering`
  )

  const serializedPages = []

  for (const page of filteredPages) {
    try {
      const { url, ...rest } = await Promise.resolve(
        serialize(page, { resolvePagePath })
      )
      serializedPages.push({
        url: prefixPath({ url, siteUrl, pathPrefix: basePath }),
        ...rest,
      })
    } catch (err) {
      reporter.panic(`${REPORTER_PREFIX} Error serializing pages`, err)
    }
  }

  const sitemapWritePath = path.join(`public`, output)
  const sitemapPublicPath = path.posix.join(pathPrefix, output)

  return simpleSitemapAndIndex({
    hostname: siteUrl,
    publicBasePath: sitemapPublicPath,
    destinationDir: sitemapWritePath,
    sourceData: serializedPages,
    limit: entryLimit,
    gzip: false,
  })
}

View on GitHub (pinned to 8b06340921)

Solutions

  1. Check the err in the panic output for the specific serialize error and which page triggered it
  2. Add null checks inside serialize: const path = page.path || ''
  3. Log the page object inside serialize to verify its shape
  4. Test serialize with the actual page objects from your GraphQL query

Example fix

// before: serialize accessing potentially missing field
serialize: (page) => ({
  url: page.path,
  changefreq: page.context.sitemap changefreq, // may be undefined
}),

// after: add defaults
serialize: (page) => ({
  url: page.path,
  changefreq: page.context?.sitemapChangefreq || `weekly`,
  priority: page.context?.sitemapPriority || 0.7,
}),
Defensive patterns

Strategy: try-catch

Validate before calling

// Test serialize with a sample page object before building
const samplePage = { path: '/test/', context: {} }
try {
  const result = serialize(samplePage, { resolvePagePath: (p) => p.path })
  if (!result || typeof result.url !== 'string') {
    throw new Error('serialize must return an object with a url property')
  }
} catch (e) {
  console.error('serialize function has a bug:', e.message)
}

Type guard

interface SerializedPage {
  url: string
  changefreq?: string
  priority?: number
}

function isSerializedPage(value: unknown): value is SerializedPage {
  return typeof value === 'object' &&
    value !== null &&
    typeof (value as { url?: unknown }).url === 'string'
}

Try / catch

// Make serialize defensive:
serialize: (page, { resolvePagePath }) => {
  const path = resolvePagePath ? resolvePagePath(page) : page.path
  if (!path) {
    throw new Error(`Page missing path: ${JSON.stringify(page)}`)
  }
  return {
    url: path,
    changefreq: page.context?.changefreq || 'weekly',
    priority: page.context?.priority || 0.7,
  }
}

Prevention

When it happens

Trigger: A custom serialize function throws (e.g. accessing page.path when page has a different shape). The default serialize encounters a page object without expected fields. serialize returns a promise that rejects.

Common situations: Custom serialize that assumes a page field exists but doesn't (e.g. page.context.slug). Pages created by other plugins with non-standard shapes. Custom serialize with a bug that only manifests on certain pages.

Related errors


AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13). Data as JSON: /api/errors/2ee3ff6d174ae223. Report an issue: GitHub.