facebook/docusaurus · error

Couldn't find the git repository root directory Failure whil

Error message

Couldn't find the git repository root directory
Failure while running ${logger.code('git rev-parse --show-toplevel')} from cwd=${logger.path(cwd)}
The command executed throws an error: ${error.message}

What it means

Thrown by getGitRepoRoot when `git rev-parse --show-toplevel` cannot even be spawned or rejects before producing a result (e.g. the cwd does not exist, is not a directory, git is missing, or the OS refuses to spawn the process). This is the rejection path of the execa promise; the exitCode path is a separate error. The original failure is attached via {cause: error}.

Source

Thrown at packages/docusaurus-utils/src/vcs/gitUtils.ts:290

      `Couldn't check if this directory is within a Git worktree: ${cwd}`,
      {cause: error},
    );
  }
}

export async function getGitRepoRoot(cwd: string): Promise<string> {
  const createErrorMessageBase = () => {
    return `Couldn't find the git repository root directory
Failure while running ${logger.code(
      'git rev-parse --show-toplevel',
    )} from cwd=${logger.path(cwd)}`;
  };

  const result = await execa('git', ['rev-parse', '--show-toplevel'], {
    cwd,
  }).catch((error) => {
    // We enter this rejection when cwd is not a dir for example
    throw new Error(
      `${createErrorMessageBase()}
The command executed throws an error: ${error.message}`,
      {cause: error},
    );
  });

  if (result.exitCode !== 0) {
    throw new Error(
      `${createErrorMessageBase()}
The command returned exit code ${logger.code(result.exitCode)}: ${logger.subdue(
        result.stderr,
      )}`,
    );
  }

  return fs.realpath.native(result.stdout.trim());
}

View on GitHub (pinned to 3f483e80e3)

Solutions

  1. Verify the cwd passed to Docusaurus exists and is a directory: `node -e "require('fs').realpathSync(process.cwd())"`.
  2. Ensure git is on PATH: `git --version` should succeed in the same shell.
  3. If siteDir is custom, point it at a real checkout rather than a parent or temp path.
  4. Run from the repository root where `.git` lives.

Example fix

// before
const root = await getGitRepoRoot(maybeDeletedDir);
// after
import fs from 'fs';
if (!fs.existsSync(maybeDeletedDir) || !fs.statSync(maybeDeletedDir).isDirectory()) {
  throw new Error(`cwd is not a directory: ${maybeDeletedDir}`);
}
const root = await getGitRepoRoot(maybeDeletedDir);
Defensive patterns

Strategy: validation

Validate before calling

import fs from 'fs';
function assertValidCwd(cwd: string) {
  const real = fs.realpathSync(cwd); // throws ENOENT if missing
  if (!fs.statSync(real).isDirectory()) throw new Error(`not a directory: ${cwd}`);
}
// run before getGitRepoRoot(cwd)

Try / catch

try {
  const root = await getGitRepoRoot(cwd);
} catch (e) {
  if (/rev-parse --show-toplevel/.test(String(e))) handleInvalidCwdOrMissingGit(e);
  else throw e;
}

Prevention

When it happens

Trigger: Calling getGitRepoRoot(cwd) (directly or transitively via getGitAllRepoRoots / VCS eager init) with a cwd that is not a valid existing directory, when git is not installed, or when spawn hits EACCES/ENOENT.

Common situations: Running a build/serve from a directory deleted mid-build, passing a relative or symlink-broken siteDir, running in a CI image without git installed, or invoking Docusaurus inside a container whose cwd was unmounted.

Related errors


AI-assisted analysis of facebook/docusaurus@3f483e80e3 (2026-08-12). Data as JSON: /api/errors/6730f9c55a748c52. Report an issue: GitHub.