{"record":{"id":"9d75d58e83a41075","repo":"gatsbyjs/gatsby","slug":"error-matchpath-property-is-undefined-for-page","errorCode":null,"errorMessage":"Error: matchPath property is undefined for page ${page.path}, should be a string","messagePattern":"Error: matchPath property is undefined for page (.+?), should be a string","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/gatsby/src/bootstrap/requires-writer.ts","lineNumber":88,"sourceCode":" * code is based on @reach/router match utility (https://github.com/reach/router/blob/152aff2352bc62cefc932e1b536de9efde6b64a5/src/lib/utils.js#L224-L254)\n */\nconst getMatchPaths = (\n  pages: Array<IGatsbyPage>\n): Array<IGatsbyPageMatchPath> => {\n  interface IMatchPathEntry extends IGatsbyPage {\n    index: number\n    score: number\n    matchPath: string\n  }\n\n  const createMatchPathEntry = (\n    page: IGatsbyPage,\n    index: number\n  ): IMatchPathEntry => {\n    const { matchPath } = page\n\n    if (matchPath === undefined) {\n      return reporter.panic(\n        `Error: matchPath property is undefined for page ${page.path}, should be a string`\n      ) as never\n    }\n\n    return {\n      ...page,\n      matchPath,\n      index,\n      score: rankRoute(matchPath),\n    }\n  }\n\n  const matchPathPages: Array<IMatchPathEntry> = []\n\n  pages.forEach((page: IGatsbyPage, index: number): void => {\n    if (page.matchPath && getPageMode(page) === `SSG`) {\n      matchPathPages.push(createMatchPathEntry(page, index))\n    }","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/gatsbyjs/gatsby/blob/8b06340921ffdf23125a365b9c9923690cb62ce6/packages/gatsby/src/bootstrap/requires-writer.ts#L70-L106","documentation":"Thrown in Gatsby's requires-writer when building the match-path index: createMatchPathEntry receives a page whose matchPath is strictly undefined. The function's type promises matchPath: string, so an undefined value is treated as a programming error and the build panics. This is a defensive invariant guard, not a normal user-facing validation.","triggerScenarios":"A page object entered into the match-path index without a matchPath field (the field is undefined). The TS type is enforced at the boundary, so this fires when internal code bypasses typing or when a plugin/third-party directly mutates the page store.","commonSituations":"Gatsby major upgrade where the IGatsbyPage/matchPath contract changed; a custom plugin mutating store pages; corrupted .cache state.","solutions":["Audit the code path that created the page: ensure matchPath is always assigned (use '' or null per the schema before this guard if a value is genuinely absent).","If you are a Gatsby contributor, normalize pages (default matchPath to a string) before they reach createMatchPathEntry.","Delete .cache and rebuild to rule out stale serialized page state from an older Gatsby version."],"exampleFix":"// before\nconst entry = createMatchPathEntry({ ...page /* matchPath missing */ }, index)\n// after\nconst entry = createMatchPathEntry({ ...page, matchPath: page.matchPath ?? `` }, index)","handlingStrategy":"type-guard","validationCode":null,"typeGuard":"// Ensure pages passed to the match-path builder always carry matchPath\nfunction isMatchPathPage(page): page is IMatchPathEntry['matchPath'] extends infer _ ? typeof page : never {\n  return typeof page?.matchPath === 'string'\n}\nif (!isMatchPathPage(page)) page = { ...page, matchPath: '' }","tryCatchPattern":null,"preventionTips":["Never construct IGatsbyPage objects without setting matchPath explicitly.","Treat matchPath as required when ingesting pages into internal indexes.","Clear .cache across Gatsby major upgrades."],"tags":["pages","matchpath","typescript","internal"],"backgroundTag":null,"analyzedSha":"8b06340921ffdf23125a365b9c9923690cb62ce6","analyzedAt":"2026-08-13T02:36:21.405Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}