{"record":{"id":"ee26c382e549de80","repo":"plandex-ai/plandex","slug":"error-committing-files-to-git-repository-for-dir","errorCode":null,"errorMessage":"error committing files to git repository for dir: %s, err: %v","messagePattern":"error committing files to git repository for dir: (.+?), err: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/git.go","lineNumber":28,"sourceCode":"\t\"time\"\n)\n\nvar gitMutex sync.Mutex\n\nfunc GitAddAndCommit(dir, message string, lockMutex bool) error {\n\tif lockMutex {\n\t\tgitMutex.Lock()\n\t\tdefer gitMutex.Unlock()\n\t}\n\n\terr := GitAdd(dir, \".\", false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error adding files to git repository for dir: %s, err: %v\", dir, err)\n\t}\n\n\terr = GitCommit(dir, message, nil, false)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error committing files to git repository for dir: %s, err: %v\", dir, err)\n\t}\n\n\treturn nil\n}\n\nfunc GitAddAndCommitPaths(dir, message string, paths []string, lockMutex bool) error {\n\tif len(paths) == 0 {\n\t\treturn nil\n\t}\n\n\tif lockMutex {\n\t\tgitMutex.Lock()\n\t\tdefer gitMutex.Unlock()\n\t}\n\n\tfor _, path := range paths {\n\t\terr := GitAdd(dir, path, false)\n\t\tif err != nil {","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/git.go#L10-L46","documentation":"After successfully staging, GitAddAndCommit runs GitCommit(dir, message, nil, false) (`git -C dir commit -m msg --allow-empty`) and wraps any failure with this error. Because --allow-empty is used, failure is rarely 'nothing to commit' — it usually indicates a git environment problem in dir.","triggerScenarios":"git commit failing due to missing/invalid user.name/user.email config, a stale .git/index.lock from a concurrent git process, a corrupted repository, or dir being read-only.","commonSituations":"Fresh machines or CI containers without git identity configured; two Plandex processes colliding on index.lock; .git owned by another user after sudo usage; detached/unusual repo states after crashes.","solutions":["Check the wrapped output for the exact git error (GitCommit includes CombinedOutput).","Configure git identity if missing: git config --global user.name / user.email.","Remove a stale lock: rm <dir>/.git/index.lock (only when no git process is running).","Fix ownership/permissions on <dir>/.git and retry the operation."],"exampleFix":"// before\n*** Please tell me who you are.  # commit fails\n// after\ngit config --global user.name \"You\"\ngit config --global user.email \"you@example.com\"","handlingStrategy":"validation","validationCode":"// Ensure git identity exists before committing\ncmd := exec.Command(\"git\", \"config\", \"--global\", \"user.email\")\nif err := cmd.Run(); err != nil {\n    // configure user.name/user.email before GitAddAndCommit\n}","typeGuard":"func isGitCommitError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"error committing files to git repository\")\n}","tryCatchPattern":"if err := lib.GitAddAndCommit(dir, msg, true); err != nil {\n    if isGitCommitError(err) {\n        log.Printf(\"git commit failed in %s: %v (check identity/index.lock)\", dir, err)\n        return\n    }\n    return err\n}","preventionTips":["Set git user.name and user.email globally on new machines/CI images.","Avoid running multiple CLI instances concurrently on the same plan dir.","Remove stale .git/index.lock only when no git process is active.","Keep .git ownership matching the running user."],"tags":["go","git","commit","subprocess"],"backgroundTag":"git-commit-failed","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}