plandex-ai/plandex · error

error resetting staged changes | err: %v, output: %s

Error message

error resetting staged changes | err: %v, output: %s

What it means

GitClearUncommittedChanges runs `git reset --hard` to discard all staged/unstaged tracked changes (from the process working directory, no -C flag). This error is returned when that reset fails, embedding the git error and output. It is destructive-by-design; a failure here usually indicates a repository-state or environment problem rather than local modifications.

Source

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

			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()
	if err != nil {
		return fmt.Errorf("error resetting staged changes | err: %v, output: %s", err, string(res))
	}

	// Clean untracked files
	res, err = exec.Command("git", "clean", "-d", "-f").CombinedOutput()
	if err != nil {
		return fmt.Errorf("error cleaning untracked files | err: %v, output: %s", err, string(res))
	}

	return nil
}

func GitFileHasUncommittedChanges(path string) (bool, error) {
	gitMutex.Lock()
	defer gitMutex.Unlock()

	res, err := exec.Command("git", "status", "--porcelain", path).CombinedOutput()
	if err != nil {
		return false, fmt.Errorf("error checking for uncommitted changes for file %s | err: %v, output: %s", path, err, string(res))

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped output for git's exact reason ('not a git repository' → chdir to repo root first).
  2. Remove a stale .git/index.lock if no git process is running.
  3. Verify git is installed and on PATH (`git --version`).
  4. If the repo state is broken, repair or re-clone; check disk space.
  5. Note: the follow-up `git clean -d -f` failure raises a different message — this one is specifically the reset step.

Example fix

// before: called from wrong cwd, reset hits non-repo
err := lib.GitClearUncommittedChanges()
// after
os.Chdir(repoRoot)
err := lib.GitClearUncommittedChanges()
Defensive patterns

Strategy: validation

Validate before calling

// Go: verify repo + git availability before destructive reset
if out, err := exec.Command("git", "rev-parse", "--is-inside-work-tree").Output(); err != nil || strings.TrimSpace(string(out)) != "true" {
    os.Chdir(repoRoot)
}
if _, err := exec.Command("git", "--version").Output(); err != nil {
    // git not installed — fail early with a clear message
}

Type guard

func isResetHardError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error resetting staged changes")
}

Try / catch

if err := lib.GitClearUncommittedChanges(); err != nil {
    if isResetHardError(err) {
        if strings.Contains(err.Error(), "index.lock") {
            os.Remove(filepath.Join(".git", "index.lock"))
            err = lib.GitClearUncommittedChanges()
        }
    }
}

Prevention

When it happens

Trigger: Calling GitClearUncommittedChanges() when cwd is not a git repository, git is missing from PATH, the index is locked (index.lock), the repo is in a conflicted/blocked state that reset --hard cannot clean, or .git is corrupt.

Common situations: Process launched outside the repo directory; concurrent git operations holding index.lock; container images without git installed; broken .git after interrupted clone or disk-full during a previous write.

Related errors


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