plandex-ai/plandex · error
conflict popping git stash: %s
Error message
conflict popping git stash: %s
What it means
GitStashPop detects a merge conflict when applying the stash — git's output contains the marker 'overwritten by merge' (PopStashConflictMsg). When forceOverwrite is false, the function refuses to resolve conflicts itself and returns this error with git's raw output instead. The caller must decide whether to retry with forceOverwrite=true.
Source
Thrown at app/cli/lib/git.go:142
func GitStashPop(forceOverwrite bool) error {
gitMutex.Lock()
defer gitMutex.Unlock()
res, err := exec.Command("git", "stash", "pop").CombinedOutput()
// we should no longer have conflicts since we are forcing an update before
// running the 'apply' command as well as resetting any files with uncommitted change
// still leaving this though in case something goes wrong
if err != nil {
log.Println("Error popping git stash:", string(res))
if strings.Contains(string(res), PopStashConflictMsg) {
log.Println("Conflicts detected")
if !forceOverwrite {
return fmt.Errorf("conflict popping git stash: %s", string(res))
}
// Parse the output to find which files have conflicts
conflictFiles := parseConflictFiles(string(res))
log.Println("Conflicting files:", conflictFiles)
for _, file := range conflictFiles {
// Reset each conflicting file individually
checkoutRes, err := exec.Command("git", "checkout", "--ours", file).CombinedOutput()
if err != nil {
return fmt.Errorf("error resetting file %s: %v", file, string(checkoutRes))
}
}
dropRes, err := exec.Command("git", "stash", "drop").CombinedOutput()
if err != nil {
return fmt.Errorf("error dropping git stash: %v", string(dropRes))
}View on GitHub (pinned to e2d772072e)
Solutions
- If overwriting local changes is acceptable, call GitStashPop(true) to force-resolve with `git checkout --ours` per conflicted file.
- Inspect the git output in the error to see which files conflict.
- Manually commit or discard the interfering local changes, then pop again.
- Re-run the operation that expects a clean tree (e.g. GitClearUncommittedChanges) before popping.
- If the stash content is no longer needed, `git stash drop` instead of popping.
Example fix
// before err := lib.GitStashPop(false) // after: force-resolve conflicts by taking current tree err := lib.GitStashPop(true)
Defensive patterns
Strategy: fallback
Validate before calling
// Go: minimize conflict window by restoring/updating the tree right before pop
if dirty, _ := lib.CheckUncommittedChanges(); dirty {
lib.GitClearUncommittedChanges()
} Type guard
func isStashConflict(err error) bool {
return err != nil && strings.Contains(err.Error(), "conflict popping git stash")
} Try / catch
if err := lib.GitStashPop(false); err != nil {
if isStashConflict(err) {
// escalate: caller decides whether local changes may be clobbered
if allowOverwrite {
err = lib.GitStashPop(true)
}
}
} Prevention
- Avoid external writes to the working tree between GitStashCreate and GitStashPop.
- Call GitClearUncommittedChanges before pop when the tree is expected clean.
- Make forceOverwrite an explicit user decision, not a silent default.
- Keep git versions consistent across environments, since conflict detection relies on output text matching.
When it happens
Trigger: Calling GitStashPop(false) after GitStashCreate when tracked files changed between stash and pop such that applying the stash would overwrite local modifications — i.e. git reports 'Your local changes to the following files would be overwritten by merge'.
Common situations: Files modified externally (editor, build tooling, another process) between stash and pop; applying a stash created before a rewind/update operation onto changed working tree; concurrent agents editing the same checkout.
Related errors
- error resetting file %s: %v
- error creating git stash: %v, output: %s
- error dropping git stash: %v
- error popping git stash: %v
- error invalidating conflicted results: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/affd6914969b4f03.
Report an issue: GitHub.