plandex-ai/plandex · error
error removing lock files: %v
Error message
error removing lock files: %v
What it means
gitRemoveIndexLockFileIfExists removes up to three git lock files (.git/index.lock, .git/refs/heads/HEAD.lock, .git/HEAD.lock) concurrently and collects every per-goroutine error. If any removal failed (see errors 375/376/377), it aggregates them into this single wrapped error. Callers are gitAdd, gitCommit, gitCheckoutBranch, gitWriteOperation, and lockRepoDB — so a failed lock cleanup blocks the subsequent git write operation.
Source
Thrown at app/server/db/git.go:641
}()
if err := removeLockFile(path); err != nil {
errCh <- err
return
}
errCh <- nil
}(path)
}
errs := []error{}
for i := 0; i < len(paths); i++ {
err := <-errCh
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return fmt.Errorf("error removing lock files: %v", errs)
}
return nil
}
func setGitConfig(repoDir, key, value string) error {
res, err := exec.Command("git", "-C", repoDir, "config", key, value).CombinedOutput()
if err != nil {
return fmt.Errorf("error setting git config %s to %s for dir: %s, err: %v, output: %s", key, value, repoDir, err, string(res))
}
return nil
}
func gitWriteOperation(operation func() error, repoDir, label string) error {
log.Printf("[Git] gitWriteOperation - label: %s", label)
var err error
for attempt := 0; attempt < maxGitRetries; attempt++ {
if attempt > 0 {View on GitHub (pinned to e2d772072e)
Solutions
- Read the aggregated inner errors to see which path failed and why (permission vs retry-exhausted vs panic).
- Fix the root cause from the inner error: chmod/chown .git, free disk space, or kill the competing git process.
- Ensure only one writer operates on the repo — use lockRepoDB/advisory locking so concurrent app instances don't fight over locks.
- If a stale lock persists, remove it manually once the owning process is confirmed dead, then retry the operation.
Example fix
// before
if err := lockRepoDB(); err != nil {
return err // opaque aggregate
}
// after: log and verify before writing
if err := lockRepoDB(); err != nil {
log.Printf("lock cleanup failed: %v; checking for live git processes", err)
// exec.Command("pgrep", "git")... abort if a git process is active
return fmt.Errorf("git write aborted, lock cleanup failed: %w", err)
} Defensive patterns
Strategy: retry
Validate before calling
for _, p := range []string{"index.lock", "HEAD.lock", filepath.Join("refs", "heads", "HEAD.lock")} {
lp := filepath.Join(repoDir, ".git", p)
if _, err := os.Stat(lp); err == nil {
if syscall.Access(filepath.Dir(lp), syscall.W_OK) != nil {
return fmt.Errorf("pre-check: cannot remove %s (permissions)", lp)
}
}
} Type guard
func isLockCleanupErr(err error) bool {
return err != nil && strings.Contains(err.Error(), "error removing lock files:")
} Try / catch
var lastErr error
for i := 0; i < 3; i++ {
if err := gitWriteOperation(op, repoDir, "commit"); err != nil {
if isLockCleanupErr(err) {
time.Sleep(time.Duration(1<<i) * 200 * time.Millisecond)
lastErr = err
continue
}
return err
}
return nil
}
return lastErr Prevention
- Serialize all git writes on a repo through lockRepoDB so only one process manipulates locks.
- Alert on this error: it usually means a crashed git process left stale locks that need manual cleanup.
- Confirm no cron/CI job runs raw git commands on the same repo concurrently.
- Monitor disk space; full disks cause cascading lock removal failures.
When it happens
Trigger: Any gitAdd/gitCommit/gitCheckoutBranch/gitWriteOperation/lockRepoDB call where at least one lock-file goroutine returned an error: removal failure (permissions), stat failure (traversal denied), >10 removal attempts without success, or a recovered panic.
Common situations: Lock files left behind by a crashed git process combined with wrong .git ownership; repo on a full or failing disk; another long-running git process re-creating locks while this function retries (11 failed attempts); multiple app instances writing the same repo concurrently.
Related errors
- error removing lock file: %v
- panic in gitRemoveIndexLockFileIfExists: %v %s
- error getting git root: %s
- error getting git status: %s
- error getting files in git repo: %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/94501c435d6ef149.
Report an issue: GitHub.