{"record":{"id":"8e2ac1a072f519fb","repo":"facebook/docusaurus","slug":"failed-to-retrieve-git-history-for-file-becau-8e2ac1","errorCode":null,"errorMessage":"Failed to retrieve git history for \"${file}\" because the file does not exist.","messagePattern":"Failed to retrieve git history for \"(.+?)\" because the file does not exist\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/docusaurus-utils/src/vcs/gitUtils.ts","lineNumber":137,"sourceCode":"    age = 'oldest',\n    includeAuthor = false,\n  }: {\n    age?: 'oldest' | 'newest';\n    includeAuthor?: boolean;\n  },\n): Promise<{\n  date: Date;\n  timestamp: number;\n  author?: string;\n}> {\n  if (!hasGit()) {\n    throw new GitNotFoundError(\n      `Failed to retrieve git history for \"${file}\" because git is not installed.`,\n    );\n  }\n\n  if (!(await fs.pathExists(file))) {\n    throw new Error(\n      `Failed to retrieve git history for \"${file}\" because the file does not exist.`,\n    );\n  }\n\n  // We add a \"RESULT:\" prefix to make parsing easier\n  // See why: https://github.com/facebook/docusaurus/pull/10022\n  const resultFormat = includeAuthor ? 'RESULT:%ct,%an' : 'RESULT:%ct';\n\n  const result = (await GitCommandQueue.add(() => {\n    return execa(\n      'git',\n      [\n        // Do not include GPG signature in the log output\n        // See https://github.com/facebook/docusaurus/pull/10022\n        '-c',\n        'log.showSignature=false',\n        'log',\n        `--format=${resultFormat}`,","sourceCodeStart":119,"sourceCodeEnd":155,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus-utils/src/vcs/gitUtils.ts#L119-L155","documentation":"Thrown by getFileCommitDate() when the file passed in does not exist on disk (fs.pathExists returns false). This guard runs after the git-installed check and before the git log invocation, ensuring the subprocess is never asked about a non-existent path. Unlike the GitNotFoundError case, this is a plain Error (not recoverable as 'untracked').","triggerScenarios":"Calling getFileCommitDate() with a path to a file that has been deleted, moved, or never existed. Commonly the path comes from a glob over docs content; if a file disappears between the glob and the per-file git query (race during dev hot-reload, partial sync, or an interrupted write) this fires.","commonSituations":"A doc file is deleted or renamed mid-build (dev server watching). An external script generates file lists that are stale by the time the build runs. A path with a typo or wrong casing that points at nothing. Cross-platform path separators (backslash on Windows) producing paths that do not exist.","solutions":["Confirm the file at the path printed in the error actually exists (ls / cat the exact path).","If the file was deleted intentionally, refresh whatever produced the file list so it no longer references the removed file.","On Windows, ensure consistent path separators and casing.","If calling getFileCommitDate directly, guard with fs.pathExists yourself and skip non-existent files rather than relying on the throw."],"exampleFix":"// before — caller assumes the file still exists\nconst info = await getFileCommitDate(filePath, { age: 'newest' });\n\n// after — guard existence\nif (!(await fs.pathExists(filePath))) return null;\nconst info = await getFileCommitDate(filePath, { age: 'newest' });","handlingStrategy":"validation","validationCode":"import fs from 'fs-extra';\n\nif (!(await fs.pathExists(file))) {\n  throw new Error(`Cannot get git history: file does not exist: ${file}`);\n}\nawait getFileCommitDate(file, { age: 'newest' });","typeGuard":null,"tryCatchPattern":"try {\n  await getFileCommitDate(file, { age: 'newest' });\n} catch (err) {\n  if (err instanceof Error && err.message.includes('the file does not exist')) {\n    // file was removed mid-build; skip it or refresh the file list\n  }\n  throw err;\n}","preventionTips":["Check fs.pathExists before calling getFileCommitDate when the file source may be stale.","Refresh glob results before per-file git queries during dev hot-reload.","Use consistent path separators (posixPath) on cross-platform builds."],"tags":["git","file-not-found","race-condition"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}