{"record":{"id":"d6607c7d8cbcee19","repo":"facebook/docusaurus","slug":"failed-to-parse-git-submodule-line-line","errorCode":null,"errorMessage":"Failed to parse git submodule line: ${line}","messagePattern":"Failed to parse git submodule line: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/docusaurus-utils/src/vcs/gitUtils.ts","lineNumber":399,"sourceCode":"    );\n  }\n\n  const output = result.stdout.trim();\n\n  if (!output) {\n    return [];\n  }\n\n  /* The output may contain a space/-/+/U prefix, for example\n     1234567e3e35d1f5b submodules/foo (heads/main)\n    -9ab1f1d3a2d77b0a4 submodules/bar (heads/dev)\n    +f00ba42e1b3ddead submodules/baz (remotes/origin/main)\n    Udeadbeefcafe1234 submodules/qux\n   */\n  const getSubmodulePath = async (line: string) => {\n    const submodulePath = line.substring(1).split(' ')[1];\n    if (!submodulePath) {\n      throw new Error(`Failed to parse git submodule line: ${line}`);\n    }\n    return submodulePath;\n  };\n\n  return Promise.all(output.split('\\n').map(getSubmodulePath));\n}\n\n// Find the root git repository alongside all its submodules, if any\nexport async function getGitAllRepoRoots(cwd: string): Promise<string[]> {\n  try {\n    const superProjectRoot = await getGitSuperProjectRoot(cwd);\n    if (!superProjectRoot) {\n      return [];\n    }\n    let submodulePaths = await getGitSubmodulePaths(superProjectRoot);\n    submodulePaths = await Promise.all(\n      submodulePaths.map((submodulePath) =>\n        fs.realpath.native(path.resolve(superProjectRoot, submodulePath)),","sourceCodeStart":381,"sourceCodeEnd":417,"githubUrl":"https://github.com/facebook/docusaurus/blob/3f483e80e326cc646b54b83d564b3f0c4881b9a6/packages/docusaurus-utils/src/vcs/gitUtils.ts#L381-L417","documentation":"Thrown by the getSubmodulePath parser inside getGitSubmodulePaths when a line from `git submodule status` does not match the expected `<prefix><sha> <path> (<branch>)` shape — specifically when `line.substring(1).split(' ')[1]` is falsy. This means git emitted a status line without a path token, which the parser cannot handle.","triggerScenarios":"A submodule path containing unusual formatting, a status line that is just a prefix+sha with no path, or a git version that emits a differently-formatted status line. Also reachable if a submodule path is empty in .gitmodules.","commonSituations":"Exotic submodule paths (leading spaces, unusual characters), corrupted submodule registration, or a git version producing non-standard output.","solutions":["Run `git submodule status` manually and inspect each line for missing/odd path tokens.","Fix the offending entry in .gitmodules and re-register the submodule.","Remove and re-add the problematic submodule if its state is unrecoverable.","Report the offending line upstream if it appears well-formed — the parser may need broadening."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"function isValidSubmoduleLine(line: string): boolean {\n  // expected: <prefix><sha> <path> (<branch>)\n  const token = line.substring(1).split(' ')[1];\n  return Boolean(token);\n}","typeGuard":"function isParsableSubmoduleLine(line: string): line is string {\n  return Boolean(line.substring(1).split(' ')[1]);\n}","tryCatchPattern":null,"preventionTips":["Inspect `git submodule status` output before relying on it.","Avoid submodule paths with leading spaces or unusual formatting.","Keep .gitmodules entries well-formed."],"tags":["git","vcs","submodule","parsing"],"backgroundTag":null,"analyzedSha":"3f483e80e326cc646b54b83d564b3f0c4881b9a6","analyzedAt":"2026-08-12T13:25:04.382Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}