{"record":{"id":"705573408e1f1876","repo":"plandex-ai/plandex","slug":"failed-to-commit-changes-s","errorCode":null,"errorMessage":"failed to commit changes: %s","messagePattern":"failed to commit changes: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/cli/lib/apply.go","lineNumber":615,"sourceCode":"\t\tfmt.Println(\"✏️  Plandex can commit these updates with an automatically generated message.\")\n\t\tfmt.Println()\n\t\t// fmt.Println(\"ℹ️  Only the files that Plandex is updating will be included the commit. Any other changes, staged or unstaged, will remain exactly as they are.\")\n\t\t// fmt.Println()\n\t\tconfirmed, err = term.ConfirmYesNo(\"Commit Plandex updates now?\")\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to get confirmation user input: %s\", err)\n\t\t}\n\t}\n\n\tif confirmed {\n\t\t// Commit the changes\n\t\tmsg := currentPlanState.PendingChangesSummaryForApply(commitSummary)\n\t\t// log.Println(\"Committing changes with message:\")\n\t\t// log.Println(msg)\n\t\t// spew.Dump(currentPlanState)\n\t\terr = GitAddAndCommitPaths(fs.ProjectRoot, msg, updatedFiles, true)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to commit changes: %s\", err.Error())\n\t\t}\n\t}\n\n\treturn nil\n}\n\nfunc ApplyFiles(toApply map[string]string, toRemove map[string]bool, projectPaths *types.ProjectPaths) ([]string, *types.ApplyRollbackPlan, error) {\n\tvar updatedFiles []string\n\ttoRevert := map[string]types.ApplyReversion{}\n\tvar toRemoveOnRollback []string\n\n\tvar mu sync.Mutex\n\ttotalOps := len(toApply) + len(toRemove)\n\terrCh := make(chan error, totalOps)\n\n\tfor path, content := range toApply {\n\t\tif path == \"_apply.sh\" {\n\t\t\terrCh <- nil","sourceCodeStart":597,"sourceCodeEnd":633,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/cli/lib/apply.go#L597-L633","documentation":"After the user confirms, commitApplied builds a commit message from the pending-changes summary and runs GitAddAndCommitPaths to commit only the updated files in the project root. This error wraps any git failure (add or commit) returned by that helper.","triggerScenarios":"GitAddAndCommitPaths(fs.ProjectRoot, msg, updatedFiles, true) fails — git executable missing, directory is not a git repo, no user.name/user.email configured, another git process holds index.lock, or a path in updatedFiles is invalid.","commonSituations":"Fresh checkout without git init; cloned repo without git config user.email/user.name; stale index.lock from a crashed git process; file paths with unusual characters or outside the repo.","solutions":["Run 'git add <file> && git commit' manually to see the underlying git error","Set git identity: git config --global user.email/user.name","Delete a stale .git/index.lock if no git process is running","Ensure the project root is a git repository (git init if needed) and that git is installed and on PATH"],"exampleFix":"// before\n$ plandex apply  # failed to commit changes: exit status 128\n// after\n$ git config user.email \"you@example.com\" && git config user.name \"You\"\n$ plandex apply","handlingStrategy":"validation","validationCode":"// pre-flight git checks\nif _, err := os.Stat(filepath.Join(fs.ProjectRoot, \".git\")); err != nil {\n  return errors.New(\"project root is not a git repository\")\n}\nif err := exec.Command(\"git\", \"-C\", fs.ProjectRoot, \"diff-index\", \"--quiet\", \"HEAD\").Run(); err != nil && !isDirtyExpected {\n  // also verifies repo + git binary work\n}\nfor _, f := range []string{\"user.email\", \"user.name\"} {\n  if out, err := exec.Command(\"git\", \"config\", f).Output(); err != nil || len(out) == 0 {\n    return fmt.Errorf(\"git config %s is not set\", f)\n  }\n}","typeGuard":null,"tryCatchPattern":"if err := GitAddAndCommitPaths(fs.ProjectRoot, msg, updatedFiles, true); err != nil {\n  if strings.Contains(err.Error(), \"index.lock\") {\n    os.Remove(filepath.Join(fs.ProjectRoot, \".git\", \"index.lock\")) // retry once\n  }\n  return fmt.Errorf(\"commit failed: %w\", err)\n}","preventionTips":["git init the project before using Plandex apply","Set git user.email/user.name globally on new machines","Clear stale .git/index.lock after crashed git processes","Keep git installed and on PATH in CI images"],"tags":["go","git","cli"],"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-12T22:17:10.623Z"}