{"record":{"id":"690abf4bc7f974c1","repo":"gatsbyjs/gatsby","slug":"the-following-page-component-must-contain-cont","errorCode":null,"errorMessage":"The following page component must contain '?__contentFilePath=':\n${cleanedComponentPath}","messagePattern":"The following page component must contain '\\?__contentFilePath=':\n(.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby-core-utils/src/parse-component-path.ts","lineNumber":23,"sourceCode":"\nconst CONTENT_FILE_PATH_QUERY = `?__contentFilePath=`\n\n// Split the path component URI without using the expensive URI.parse()\nexport const splitComponentPath = (componentPath: string): Array<string> => {\n  // If the path does not include the contentFilePath query, we can assume its a regular path\n  if (!componentPath.includes(CONTENT_FILE_PATH_QUERY)) {\n    return [componentPath]\n  }\n\n  const cleanedComponentPath = componentPath.replace(\n    /&export=(default|head)$/,\n    ``\n  )\n  const splitPath = cleanedComponentPath.split(CONTENT_FILE_PATH_QUERY)\n\n  // We only support URI paths with the `?__contentFilePath=` parameter\n  if (splitPath.length !== 2) {\n    throw new Error(\n      `The following page component must contain '${CONTENT_FILE_PATH_QUERY}':\\n${cleanedComponentPath}`\n    )\n  }\n\n  return splitPath\n}\n\n// Get the path to the actual js page component\nexport const getPathToLayoutComponent = (componentPath: string): string =>\n  splitComponentPath(componentPath)[0]\n\n// Get the path to the content file, falling back to the js component if no content file is given.\n// Pages directly created from `.mdx` files\nexport const getPathToContentComponent = (componentPath: string): string => {\n  const splitPath = splitComponentPath(componentPath)\n  if (splitPath.length === 1) {\n    return splitPath[0]\n  }","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby-core-utils/src/parse-component-path.ts#L5-L41","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Inspect cleanedComponentPath in the message to see where the duplicate/misplaced marker sits.","Ensure createPage's component argument is the bare JS path; the __contentFilePath query is added internally, not by user code.","If constructing component strings manually, append __contentFilePath exactly once and never inline it in the path.","Upgrade gatsby-core-utils / gatsby to a version where page-creator builds the string correctly."],"exampleFix":"// before: marker appended twice\nconst component = `${jsPath}?__contentFilePath=${mdx}?__contentFilePath=${mdx2}`\n// after: single marker\nconst component = `${jsPath}?__contentFilePath=${mdx}`","handlingStrategy":"validation","validationCode":"const occurrences = (componentPath.split(CONTENT_FILE_PATH_QUERY).length - 1)\nif (componentPath.includes(CONTENT_FILE_PATH_QUERY) && occurrences !== 1) {\n  throw new Error(`component path has ${occurrences} markers; expected exactly 1`)\n}","typeGuard":"const hasSingleContentMarker = (p: string): boolean =>\n  !p.includes(CONTENT_FILE_PATH_QUERY) || p.split(CONTENT_FILE_PATH_QUERY).length === 2","tryCatchPattern":null,"preventionTips":["Never inline __contentFilePath in user-built component strings.","Let page-creator add the marker; pass only the JS path to createPage.","Sanitize component paths before parsing."],"tags":["parse-component-path","routing","mdx","gatsby-core-utils"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}