mastra-ai/mastra · error

Not a git repository: ${dir}

Error message

Not a git repository: ${dir}

What it means

GitHistoryStorage resolves a file path relative to the discovered git repository root; relativeToRepo throws when no repo root was cached/resolved for the storage directory, meaning the directory is not inside a git work tree. The path-based storage cannot record history without git metadata.

Source

Thrown at packages/core/src/storage/git-history.ts:173

   * (e.g., the user commits or pulls).
   */
  invalidateCache(): void {
    this.repoRootCache.clear();
    this.commitCache.clear();
    this.snapshotCache.clear();
  }

  // ===========================================================================
  // Internals
  // ===========================================================================

  /**
   * Get the relative path from the Git repo root to a file in the storage directory.
   */
  private relativeToRepo(dir: string, filename: string): string {
    const root = this.repoRootCache.get(dir);
    if (!root) {
      throw new Error(`Not a git repository: ${dir}`);
    }
    // Resolve symlinks so that macOS /var → /private/var differences don't break relative()
    const realRoot = realpathSync(root);
    const realDir = realpathSync(dir);
    const relDir = relative(realRoot, realDir);
    return relDir ? `${relDir}/${filename}` : filename;
  }

  /**
   * Execute a git command and return stdout.
   */
  private exec(cwd: string, args: string[]): Promise<string> {
    return new Promise((resolve, reject) => {
      execFile('git', args, { cwd, maxBuffer: 10 * 1024 * 1024 }, (error, stdout) => {
        if (error) reject(error);
        else resolve(stdout);
      });
    });

View on GitHub (pinned to 75dd419e61)

Solutions

  1. Run `git init` in (or move storage under) a directory inside a git work tree.
  2. Ensure the .git directory is present in deployments (don't strip it from the build artifact).
  3. Configure the storage to point at a path inside the existing repository root.

Example fix

// before
const storage = new FilesystemVersionedStorage({ dir: '/tmp/cache' }); // no git
// after
mkdirSync(dir, { recursive: true });
execSync('git init', { cwd: dir });
const storage = new FilesystemVersionedStorage({ dir });
Defensive patterns

Strategy: validation

Validate before calling

import { existsSync } from 'node:fs';
import { execSync } from 'node:child_process';
if (!existsSync(`${dir}/.git`)) {
  execSync(`git init ${dir}`);
}

Try / catch

try {
  await storage.list(...);
} catch (e) {
  if (String(e.message).startsWith('Not a git repository')) {
    execSync(`git init ${storageDir}`); // then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Instantiating the storage with a directory outside any git repository (or with git metadata missing); repoRootCache not populated because resolveRepoRoot failed for that dir; using a temp dir that was created without git init; calling relPath before initialization.

Common situations: Deployed containers running from a directory copied without the .git folder; tests writing to a bare tmpdir; monorepo where the storage dir sits above the git root.

Related errors


AI-assisted analysis of mastra-ai/mastra@75dd419e61 (2026-08-30). Data as JSON: /api/errors/9dfa85a71f0118f6. Report an issue: GitHub.