gatsbyjs/gatsby · error

The following page component must contain '?__contentFilePat

Error message

The following page component must contain '?__contentFilePath=':
${cleanedComponentPath}

What it means

Thrown by parse-component-path's splitComponentPath when a component path contains the CONTENT_FILE_PATH_QUERY marker but, after stripping the &export= suffix and splitting, yields more than two segments. The function expects exactly one '?__contentFilePath=' separator; multiple occurrences or a malformed URI break the invariant.

Source

Thrown at packages/gatsby-core-utils/src/parse-component-path.ts:23

const CONTENT_FILE_PATH_QUERY = `?__contentFilePath=`

// Split the path component URI without using the expensive URI.parse()
export const splitComponentPath = (componentPath: string): Array<string> => {
  // If the path does not include the contentFilePath query, we can assume its a regular path
  if (!componentPath.includes(CONTENT_FILE_PATH_QUERY)) {
    return [componentPath]
  }

  const cleanedComponentPath = componentPath.replace(
    /&export=(default|head)$/,
    ``
  )
  const splitPath = cleanedComponentPath.split(CONTENT_FILE_PATH_QUERY)

  // We only support URI paths with the `?__contentFilePath=` parameter
  if (splitPath.length !== 2) {
    throw new Error(
      `The following page component must contain '${CONTENT_FILE_PATH_QUERY}':\n${cleanedComponentPath}`
    )
  }

  return splitPath
}

// Get the path to the actual js page component
export const getPathToLayoutComponent = (componentPath: string): string =>
  splitComponentPath(componentPath)[0]

// Get the path to the content file, falling back to the js component if no content file is given.
// Pages directly created from `.mdx` files
export const getPathToContentComponent = (componentPath: string): string => {
  const splitPath = splitComponentPath(componentPath)
  if (splitPath.length === 1) {
    return splitPath[0]
  }

View on GitHub (pinned to 8b06340921)

Solutions

  1. Inspect cleanedComponentPath in the message to see where the duplicate/misplaced marker sits.
  2. Ensure createPage's component argument is the bare JS path; the __contentFilePath query is added internally, not by user code.
  3. If constructing component strings manually, append __contentFilePath exactly once and never inline it in the path.
  4. Upgrade gatsby-core-utils / gatsby to a version where page-creator builds the string correctly.

Example fix

// before: marker appended twice
const component = `${jsPath}?__contentFilePath=${mdx}?__contentFilePath=${mdx2}`
// after: single marker
const component = `${jsPath}?__contentFilePath=${mdx}`
Defensive patterns

Strategy: validation

Validate before calling

const occurrences = (componentPath.split(CONTENT_FILE_PATH_QUERY).length - 1)
if (componentPath.includes(CONTENT_FILE_PATH_QUERY) && occurrences !== 1) {
  throw new Error(`component path has ${occurrences} markers; expected exactly 1`)
}

Type guard

const hasSingleContentMarker = (p: string): boolean =>
  !p.includes(CONTENT_FILE_PATH_QUERY) || p.split(CONTENT_FILE_PATH_QUERY).length === 2

Prevention

When it happens

Trigger: A page component path string containing two or more '?__contentFilePath=' substrings, or a path where the marker appears inside the file path itself; calling getPathToLayoutComponent/getPathToContentComponent on such a malformed string.

Common situations: Routing/page-creator bugs that concatenate a content file path twice; manual createPage calls building the component string incorrectly; SSG/MDX integration that appends __contentFilePath more than once when nesting layouts.

Related errors


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