plandex-ai/plandex · error
error committing convo message: %v
Error message
error committing convo message: %v
What it means
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).
Source
Thrown at app/server/db/convo_helpers.go:200
}
if message.Flags.DidCompletePlan {
msg += "\n\n" + "🏁 Completed Plan"
}
// Cleaner without the cut off message - maybe need a separate command to show both the log and full messages?
// cutoff := 140
// if len(message.Message) > cutoff {
// msg += "\n\n" + message.Message[:cutoff] + "..."
// } else {
// msg += "\n\n" + message.Message
// }
if commit {
log.Printf("[Git] StoreConvoMessage - committing convo message: %s, branch: %s", msg, branch)
err = repo.GitAddAndCommit(branch, msg)
if err != nil {
return "", fmt.Errorf("error committing convo message: %v", err)
}
}
return msg, nil
}
View on GitHub (pinned to e2d772072e)
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
Example fix
// before
err = repo.GitAddAndCommit(branch, msg) // concurrent partials collide
// after
if isPartial {
return msg, nil // skip commit for partial replies
}
err = repo.GitAddAndCommit(branch, msg) Defensive patterns
Strategy: try-catch
Validate before calling
if commit {
if _, err := os.Stat(filepath.Join(repoPath, ".git")); err != nil {
return fmt.Errorf("not a git repo: %v", err)
}
if !branchExists(repo, branch) {
return fmt.Errorf("branch %s does not exist", branch)
}
} Try / catch
msg, err := db.StoreConvoMessage(ctx, m, branch, true)
if err != nil && strings.Contains(err.Error(), "error committing convo message") {
log.Printf("git commit failed: %v — message stored, commit skipped", err)
// enqueue a retry of GitAddAndCommit alone
return err
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- error invalidating conflicted results: %v
- panic in gitRemoveIndexLockFileIfExists: %v %s
- error removing lock files: %v
- operation %s failed after %d attempts: %v
- error accepting invite: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/c0779226a8ab7773.
Report an issue: GitHub.