{"record":{"id":"8040aa3c14d8f0e0","repo":"plandex-ai/plandex","slug":"error-adding-files-to-git-repository-for-dir-s","errorCode":null,"errorMessage":"error adding files to git repository for dir: %s, err: %v","messagePattern":"error adding files to git repository for dir: (.+?), err: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/git.go","lineNumber":23,"sourceCode":"\t\"log\"\n\t\"os/exec\"\n\t\"regexp\"\n\t\"strings\"\n\t\"sync\"\n\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()","sourceCodeStart":5,"sourceCodeEnd":41,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/git.go#L5-L41","documentation":"GitAddAndCommit stages all changes ('.') in dir via GitAdd and wraps any failure with this message. GitAdd shells out to `git -C <dir> add .`, so this error means the git add subprocess failed — usually because dir is not a git repository or contains no addable state.","triggerScenarios":"Calling GitAddAndCommit with a dir that is not a git repository (no .git), a nonexistent dir, a corrupted .git, or with git not on PATH; the wrapped error carries the exec output from GitAdd.","commonSituations":"Project plans directory missing its .git after interrupted setup or manual cleanup; passing the wrong directory path; CI environments where git is not installed; permissions on .git preventing writes to the index.","solutions":["Verify dir is a git repository: run `git -C <dir> status`; if it fails, run `git -C <dir> init`.","Check the wrapped err/output (GitAdd includes CombinedOutput) for the exact git failure (e.g. 'not a git repository', 'fatal: ...').","Ensure git is installed and on PATH in the environment.","Fix .git permissions if the index.lock is unwritable, and remove a stale .git/index.lock if present."],"exampleFix":"// before\n# dir lost its .git after an interrupted update\n// after\ngit -C <dir> init && retry the plandex operation\n(or restore the plans directory from backup)","handlingStrategy":"validation","validationCode":"// Verify the target is a git repo before GitAddAndCommit\nimport \"os/exec\"\nfunc isGitRepo(dir string) bool {\n    return exec.Command(\"git\", \"-C\", dir, \"rev-parse\", \"--git-dir\").Run() == nil\n}\n// if !isGitRepo(dir) { git -C dir init || fix dir }","typeGuard":"func isGitAddError(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"error adding files to git repository\")\n}","tryCatchPattern":"if err := lib.GitAddAndCommit(dir, msg, true); err != nil {\n    if isGitAddError(err) {\n        log.Printf(\"git add failed for %s: %v\", dir, err)\n        // inspect .git state, possibly re-init\n        return\n    }\n    return err\n}","preventionTips":["Ensure the plans/context directory is initialized as a git repo before operations.","Don't delete or move .git inside Plandex-managed directories.","Confirm git is installed and on PATH, especially in CI containers.","Clear stale .git/index.lock files if concurrent operations were interrupted."],"tags":["go","git","subprocess","add"],"backgroundTag":"git-command-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"}