plandex-ai/plandex · warning

error dropping git stash: %v

Error message

error dropping git stash: %v

What it means

After resolving stash-pop conflicts with `git checkout --ours`, GitStashPop drops the stash with `git stash drop`. This error wraps a failure of that drop command, including git's output. The conflicted files were reset, but the stash entry remains, so the working tree is resolved but the stash is not cleaned up.

Source

Thrown at app/cli/lib/git.go:159

			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))
			}
			return nil
		} else {
			log.Println("No conflicts detected")

			return fmt.Errorf("error popping git stash: %v", string(res))
		}
	}

	return nil
}

func GitClearUncommittedChanges() error {
	gitMutex.Lock()
	defer gitMutex.Unlock()

	// Reset staged changes
	res, err := exec.Command("git", "reset", "--hard").CombinedOutput()

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check `git stash list`; if the message is 'No stash entries found', the stash is already gone and this is harmless — proceed.
  2. Remove stale .git/index.lock if a git process is stuck.
  3. If the stash ref is corrupted, delete it: `git stash clear` or remove .git/refs/stash.
  4. Retry the drop manually: `git stash drop` and verify output.
  5. Ensure only one process manipulates the stash stack at a time.

Example fix

// before: treating drop failure as fatal even when stash is empty
if err := lib.GitStashPop(true); err != nil { return err }
// after: tolerate missing stash
if err := lib.GitStashPop(true); err != nil && strings.Contains(err.Error(), "No stash entries") {
    err = nil // stash already gone
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Go: confirm a stash exists before pop/drop
out, err := exec.Command("git", "stash", "list").Output()
hasStash := err == nil && strings.TrimSpace(string(out)) != ""

Type guard

func isStashDropError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error dropping git stash")
}

Try / catch

if err := lib.GitStashPop(true); err != nil {
    if isStashDropError(err) && strings.Contains(err.Error(), "No stash entries") {
        err = nil // stash already consumed; treat as success
    }
}

Prevention

When it happens

Trigger: GitStashPop(true) successfully reset all conflict files, then `git stash drop` failed — usually because there is no stash entry left (it was already popped/dropped or never created), the reflog/stash ref is corrupted, or the index is locked.

Common situations: Another process or a prior crashed run already consumed the stash (`No stash entries found`); concurrent GitStashPop calls racing on the same stash stack despite the mutex; corrupted .git/refs/stash.

Related errors


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/6c3561a0e71835ee. Report an issue: GitHub.