{"record":{"id":"c0779226a8ab7773","repo":"plandex-ai/plandex","slug":"error-committing-convo-message-v","errorCode":null,"errorMessage":"error committing convo message: %v","messagePattern":"error committing convo message: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/convo_helpers.go","lineNumber":200,"sourceCode":"\t}\n\n\tif message.Flags.DidCompletePlan {\n\t\tmsg += \"\\n\\n\" + \"🏁 Completed Plan\"\n\t}\n\n\t// Cleaner without the cut off message - maybe need a separate command to show both the log and full messages?\n\t// cutoff := 140\n\t// if len(message.Message) > cutoff {\n\t// \tmsg += \"\\n\\n\" + message.Message[:cutoff] + \"...\"\n\t// } else {\n\t// \tmsg += \"\\n\\n\" + message.Message\n\t// }\n\n\tif commit {\n\t\tlog.Printf(\"[Git] StoreConvoMessage - committing convo message: %s, branch: %s\", msg, branch)\n\t\terr = repo.GitAddAndCommit(branch, msg)\n\t\tif err != nil {\n\t\t\treturn \"\", fmt.Errorf(\"error committing convo message: %v\", err)\n\t\t}\n\t}\n\n\treturn msg, nil\n}\n","sourceCodeStart":182,"sourceCodeEnd":206,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/convo_helpers.go#L182-L206","documentation":"StoreConvoMessage wraps failures from repo.GitAddAndCommit, which stages and commits the conversation message file on the given git branch. The message was already saved to the DB; only the git commit step failed. The wrapped error carries git's own diagnostics (e.g. merge conflicts, missing branch).","triggerScenarios":"commit=true passed to StoreConvoMessage while GitAddAndCommit fails: branch does not exist or is checked out elsewhere, git index locked (.git/index.lock), merge conflict, or the repo working tree is in a dirty/detached state.","commonSituations":"Concurrent streaming replies committing to the same branch causing index.lock contention; a plan branch was rebased/deleted mid-conversation; read-only filesystem or missing git identity (user.name/user.email) in containers.","solutions":["Read the wrapped git error for the exact cause (lock, conflict, missing branch)","Remove stale .git/index.lock if concurrent commits collided, or serialize commits per branch","Ensure the target branch exists (create it) and git user.name/user.email are configured","Set commit=false for high-frequency partial replies and commit only final messages"],"exampleFix":"// before\nerr = repo.GitAddAndCommit(branch, msg) // concurrent partials collide\n// after\nif isPartial {\n    return msg, nil // skip commit for partial replies\n}\nerr = repo.GitAddAndCommit(branch, msg)","handlingStrategy":"try-catch","validationCode":"if commit {\n    if _, err := os.Stat(filepath.Join(repoPath, \".git\")); err != nil {\n        return fmt.Errorf(\"not a git repo: %v\", err)\n    }\n    if !branchExists(repo, branch) {\n        return fmt.Errorf(\"branch %s does not exist\", branch)\n    }\n}","typeGuard":null,"tryCatchPattern":"msg, err := db.StoreConvoMessage(ctx, m, branch, true)\nif err != nil && strings.Contains(err.Error(), \"error committing convo message\") {\n    log.Printf(\"git commit failed: %v — message stored, commit skipped\", err)\n    // enqueue a retry of GitAddAndCommit alone\n    return err\n}","preventionTips":["Serialize commits per branch or use a file lock to avoid index.lock collisions","Set commit=false for high-frequency partial replies; commit only final messages","Configure git user.name/user.email in deployment images","Ensure target branches exist before streaming replies into them"],"tags":["git","database","concurrency"],"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"}