gatsbyjs/gatsby · error
Collection page builder encountered an error parsing the fil
Error message
Collection page builder encountered an error parsing the filepath. To use collection paths the schema to follow is {Model.field__subfield}. The problematic part is: ${part}. What it means
gatsby-plugin-page-creator supports file-system routing with collection segments like `{Model.field__subfield}` (e.g. src/pages/{Product.name}.js). is-valid-collection-path-implementation.ts parses each path part and extracts the Model (word before the first dot) and the field chain (everything after the first dot) via regex. If either capture yields zero matches, or the counts of captured models and fields do not match, the part is rejected with this error. It indicates structurally malformed collection syntax (missing model, missing field, unbalanced braces, or extra dots).
Source
Thrown at packages/gatsby-plugin-page-creator/src/is-valid-collection-path-implementation.ts:29
filePath: string,
reporter: Reporter
): boolean {
const parts = filePath.split(sysPath.sep)
let passing = false
let errors = 0
parts.forEach(part => {
if (!part.includes(`{`) && !part.includes(`}`)) return
const model = Array.from(part.matchAll(/\{([a-zA-Z_]\w*)./g)) // Search for word before first dot, e.g. Model
const field = Array.from(part.matchAll(/.*?((?<=\w\.)[^}]*)}/g)) // Search for everything after the first dot, e.g. foo__bar (or in invalid case: foo.bar)
try {
if (
model.length === 0 ||
field.length === 0 ||
model.length !== field.length
) {
throw new Error(errorMessage(part))
}
const models = Array.from(model, m => m[1])
const fields = Array.from(field, f => f[1])
for (const m of models) {
assert(m, /^[a-zA-Z_]\w*$/, errorMessage(part)) // Check that Model is https://spec.graphql.org/draft/#sec-Names
}
for (const f of fields) {
assert(f, /^[a-zA-Z_][\w_()]*$/, errorMessage(part)) // Check that field is foo__bar__baz (and not foo.bar.baz) + https://spec.graphql.org/draft/#sec-Names
}
} catch (e) {
reporter.panicOnBuild({
id: prefixId(CODES.CollectionPath),
context: {
sourceMessage: e.message,
},
filePath: filePath,View on GitHub (pinned to 8b06340921)
Solutions
- Rewrite the filename to the {Model.field} form using __ for nested fields, e.g. {Product.category__slug}.js.
- Ensure exactly one {Model.field} token per path segment; split multiple tokens across separate path segments.
- Remove any stray curly braces from filenames that are not meant to be collection markers.
- Confirm the Model name matches an existing Gatsby node type (e.g. Mdx, MarkdownRemark) and the field is a valid GraphQL field on that type.
Example fix
// before
src/pages/{Product.category.slug}.js // dots are illegal in the field part
// after
src/pages/{Product.category__slug}.js // __ separates subfields Defensive patterns
Strategy: validation
Validate before calling
const COLLECTION_PART = /\{([a-zA-Z_]\w*)\.([^}]+)\}/;
function isValidCollectionPart(part) {
if (!part.includes('{') && !part.includes('}')) return true;
const models = Array.from(part.matchAll(/\{([a-zA-Z_]\w*)\./g));
const fields = Array.from(part.matchAll(/.*?((?<=\w\.)[^}]*)}/g));
return models.length > 0 && models.length === fields.length;
} Type guard
function isCollectionPath(p) {
return p.split('/').every(part => {
if (!part.includes('{')) return true;
const models = Array.from(part.matchAll(/\{([a-zA-Z_]\w*)\./g));
const fields = Array.from(part.matchAll(/.*?((?<=\w\.)[^}]*)}/g));
return models.length > 0 && models.length === fields.length &&
models.every(m => /^[a-zA-Z_]\w*$/.test(m[1]));
});
} Prevention
- Use the {Model.field__subfield} form with __ for subfields, never dots.
- Keep exactly one {Model.field} marker per path segment.
- Add a prebuild lint that scans src/pages for malformed collection filenames.
When it happens
Trigger: A file under src/pages whose name contains `{...}` but breaks the schema: `{.field}` (no Model), `{Model.}` (no field), `{Model.field.subfield}` (dots instead of __), `{Model.}` (trailing dot), or two collection markers in one segment like `{A.x}{B.y}` producing mismatched model/field counts. Also triggered by stray braces in a filename like `foo{bar}.js`.
Common situations: Coming from Next.js dynamic routes (`[slug]`) and using dots instead of the Gatsby `__` separator; copy-pasting a GraphQL field path with dots into the filename; accidentally leaving a literal `{` in a filename; renaming a model field but not the file.
Related errors
- An error occurred building the slug parts. This is likely a
- PageCreator: To query node "gatsbyPath" the "filePath" argum
- PageCreator: To query node "gatsbyPath" the "filePath" argum
- PageCreator: To query node "gatsbyPath" the "filePath" argum
- PageCreator: To query node "gatsbyPath" the "filePath" argum
AI-assisted analysis of gatsbyjs/gatsby@8b06340921 (2026-08-13).
Data as JSON: /api/errors/5db549827417f656.
Report an issue: GitHub.