thedotmack/claude-mem · warning

Git operation failed: git -C ${cwd} ${args.join(' ')}

Error message

Git operation failed: git -C ${cwd} ${args.join(' ')}

What it means

WorktreeAdoption shells out to git via spawnSync with a timeout and logs slow operations over 1s. This warning fires when r.error is set — git could not be spawned at all (ENOENT: git not installed or not on PATH) or the command exceeded GIT_TIMEOUT_MS and was killed (ETIMEDOUT/SIGTERM). The helper returns null and git-dependent adoption is skipped; ordinary non-zero git exits are logged separately at debug level.

Source

Thrown at src/services/infrastructure/WorktreeAdoption.ts:65

    this.name = 'DryRunRollback';
  }
}

function gitCapture(cwd: string, args: string[]): string | null {
  const startTime = Date.now();
  const r = spawnSync('git', ['-C', cwd, ...args], {
    encoding: 'utf8',
    timeout: GIT_TIMEOUT_MS,
    windowsHide: true
  });
  const duration = Date.now() - startTime;
  
  if (duration > 1000) {
    logger.debug('GIT', `Slow git operation: git -C ${cwd} ${args.join(' ')} took ${duration}ms`);
  }

  if (r.error) {
    logger.warn('GIT', `Git operation failed: git -C ${cwd} ${args.join(' ')}`, {
      error: r.error.message,
      timedOut: r.error.name === 'ETIMEDOUT' || (r.status === null && r.signal === 'SIGTERM')
    });
    return null;
  }

  if (r.status !== 0) {
    logger.debug('GIT', `Git returned non-zero exit code ${r.status}: git -C ${cwd} ${args.join(' ')}`, {
      stderr: r.stderr?.toString().trim()
    });
    return null;
  }
  return (r.stdout ?? '').trim();
}

function resolveMainRepoPath(cwd: string): string | null {
  const commonDir = gitCapture(cwd, [
    'rev-parse',

View on GitHub (pinned to e2d1df569a)

Solutions

  1. Confirm `git --version` works in the environment claude-mem runs in — services and GUI apps inherit a different PATH than your shell.
  2. If the log's timedOut flag is true, identify the slow operation (large repo, hung remote, locked index) and fix or prune it.
  3. Install git or add its directory to PATH, then restart the worker.
  4. For hanging credential prompts, configure a non-interactive credential helper (cache or store).
Defensive patterns

Strategy: validation

Validate before calling

// prove git is invokable from this process before adoption runs
import { spawnSync } from 'node:child_process';

const probe = spawnSync('git', ['--version'], { encoding: 'utf8' });
if (probe.error || probe.status !== 0) {
  throw new Error('git not available on PATH of this process');
}

Try / catch

const r = spawnSync('git', args, { timeout: GIT_TIMEOUT_MS });
if (r.error || r.status !== 0) {
  // null result means 'skip git-dependent work', not a crash
  skipAdoptionFor(cwd);
}

Prevention

When it happens

Trigger: spawnSync('git', ...) errors: 'git' absent from the PATH of the claude-mem process (ENOENT), the command exceeding GIT_TIMEOUT_MS on a huge or hung repo (ETIMEDOUT, SIGTERM), or an invalid cwd making the spawn fail.

Common situations: git not on PATH for GUI-launched or service contexts where PATH differs from the shell; CI containers without git; network filesystems making git status hang; a credential helper prompting indefinitely on a private remote.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


AI-assisted analysis of thedotmack/claude-mem@e2d1df569a (2026-08-20). Data as JSON: /api/errors/f9462a2c42f91713. Report an issue: GitHub.