{"record":{"id":"fc2c670b7dce3f52","repo":"getzola/zola","slug":"failed-to-parse-page-s-msg","errorCode":null,"errorMessage":"Failed to parse {} page(s):\n{msg}","messagePattern":"Failed to parse (.+?) page\\(s\\):\n(.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"components/site/src/lib.rs","lineNumber":297,"sourceCode":"            }\n        }\n        let results: Vec<(PathBuf, Result<Page>)> = page_paths\n            .par_iter()\n            .map(|p| (p.clone(), Page::from_file(p, &self.config, &self.base_path)))\n            .collect();\n        let (pages, errors): (Vec<_>, Vec<_>) = results.into_iter().partition(|(_, r)| r.is_ok());\n\n        if !errors.is_empty() {\n            let mut errors: Vec<_> = errors.into_iter().map(|(p, r)| (p, r.unwrap_err())).collect();\n            // sort by path for deterministic output\n            errors.sort_by(|(a, _), (b, _)| a.cmp(b));\n\n            let msg = errors\n                .iter()\n                .map(|(p, e)| format!(\"  - {}: {e}\", p.display()))\n                .collect::<Vec<_>>()\n                .join(\"\\n\");\n            return Err(anyhow!(\"Failed to parse {} page(s):\\n{msg}\", errors.len()));\n        }\n\n        let pages: Vec<Page> = pages.into_iter().map(|(_, r)| r.unwrap()).collect();\n        self.create_default_index_sections()?;\n\n        for page in pages {\n            // should we skip drafts?\n            if page.meta.draft && !self.include_drafts {\n                continue;\n            }\n\n            // We are only checking it on load and not in add_page since we have access to\n            // all the components there.\n            if page.file.filename == \"index.md\" {\n                let is_invalid = match page.components.last() {\n                    Some(_) => sections.contains(&page.components.join(\"/\")),\n                    // content/index.md is always invalid, but content/colocated/index.md is ok\n                    None => page.file.colocated_path.is_none(),","sourceCodeStart":279,"sourceCodeEnd":315,"githubUrl":"https://github.com/getzola/zola/blob/61d30828217957120309db657950224edf9707e2/components/site/src/lib.rs#L279-L315","documentation":"During site `load`, Zola parses all content pages in parallel and collects per-file parse errors. If any page fails to parse, `load` aborts and returns this anyhow error aggregating the count of failed pages and a bulleted list of `path: error` messages.","triggerScenarios":"Any content file under the `content/` directory that fails front-matter or markdown parsing while building/serving — e.g. invalid TOML/YAML front matter, unclosed delimiters, wrong front-matter format — causing the `errors` map in `load` to be non-empty.","commonSituations":"Malformed TOML in a page's front matter (missing quotes, wrong types like string vs integer for a config field); YAML tabs; forgetting to close `+++`/`---` delimiters; a partially-edited or merged content file with syntax errors; wrong front-matter language marker for the site config.","solutions":["Read the per-file messages listed under the summary (each '  - <path>: <error>' line) and fix the first listed file's front-matter/markdown syntax","Validate front matter delimiters match (+++ for TOML, --- for YAML) and are closed","Check field types against Zola's page config schema (e.g. dates as strings in TOML, template as string)","Run `zola build` after each fix to see remaining failures"],"exampleFix":"// before (content/post.md)\n+++\ntitle = Broken quote\ndate = 2024-01-01\n// after\n+++\ntitle = \"Broken quote\"\ndate = \"2024-01-01\"","handlingStrategy":"validation","validationCode":"import Toml from '@iarna/toml';\nimport fs from 'fs';\nexport function validateFrontMatter(file) {\n  const text = fs.readFileSync(file, 'utf8');\n  const m = text.match(/^\\+\\+\\+([\\s\\S]*?)\\+\\+\\+/);\n  if (!m) throw new Error(`${file}: missing/closed +++ front matter`);\n  try { Toml.parse(m[1]); } catch (e) { throw new Error(`${file}: ${e.message}`); }\n}\ncontentFiles().forEach(validateFrontMatter);","typeGuard":"function hasValidDelimiters(text) {\n  const m = text.match(/^(\\+\\+\\+|---)([\\s\\S]*?)^\\1/m);\n  return m != null;\n}","tryCatchPattern":"match site.load() {\n    Ok(_) => build(site),\n    Err(e) if e.to_string().starts_with(\"Failed to parse \") => {\n        eprintln!(\"{e:#}\"); // prints the per-file bullet list for fixing\n        std::process::exit(1);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Run `zola build` (or a CI content-lint step) on every commit so parse errors surface immediately","Keep front matter delimiters consistent (+++ TOML / --- YAML) and closed on their own line","Quote all string front-matter values and check field types against the Zola docs schema","Enable editor TOML/YAML syntax highlighting for the front-matter block to catch typos early"],"tags":["content","parsing","front-matter","build"],"backgroundTag":"front-matter-parse-error","analyzedSha":"61d30828217957120309db657950224edf9707e2","analyzedAt":"2026-09-03T14:39:09.727Z","contentChangedAt":"2026-09-03T14:39:09.727Z","schemaVersion":2},"datasetVersion":"2026-09-10T17:17:09.494Z"}