plandex-ai/plandex · error

error checking out file %s | err: %v, output: %s

Error message

error checking out file %s | err: %v, output: %s

What it means

GitCheckoutFile runs `git checkout <path>` to revert a single file to HEAD. This error means that command failed; the git stderr is logged and embedded in the message. Typical causes include the file being untracked or unknown to the index, so there is no committed version to restore.

Source

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

	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))
	}

	return strings.TrimSpace(string(res)) != "", nil
}

func GitCheckoutFile(path string) error {
	gitMutex.Lock()
	defer gitMutex.Unlock()

	res, err := exec.Command("git", "checkout", path).CombinedOutput()
	if err != nil {
		log.Println("Error checking out file:", string(res))

		return fmt.Errorf("error checking out file %s | err: %v, output: %s", path, err, string(res))
	}

	return nil
}

const GitLogTimestampFormat = "Mon Jan 2, 2006 | 3:04:05pm"

var GitLogTimestampRegex = regexp.MustCompile(`\w{3} \w{3} \d{1,2}, \d{4} \| \d{1,2}:\d{2}:\d{2}(am|pm) UTC`)

func GetGitLogTimestamp(log string) (time.Time, error) {
	matches := GitLogTimestampRegex.FindStringSubmatch(log)
	if len(matches) < 2 {
		return time.Time{}, fmt.Errorf("no timestamp found in log")
	}

	return time.Parse(GitLogTimestampFormat, strings.TrimSuffix(matches[0], " UTC"))
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the file is tracked: `git ls-files --error-unmatch <path>`; untracked files cannot be checked out.
  2. Guard the call with GitFileHasUncommittedChanges and skip checkout for untracked files.
  3. Fix the path (relative to repo root, correct spelling).
  4. Confirm cwd is a git repo and the git binary exists on PATH.

Example fix

// before
if dirty, _ := GitFileHasUncommittedChanges(path); dirty {
    GitCheckoutFile(path)
}
// after
tracked, _ := exec.Command("git", "ls-files", "--error-unmatch", path).Run() == nil
if tracked {
    if dirty, _ := GitFileHasUncommittedChanges(path); dirty {
        GitCheckoutFile(path)
    }
}
Defensive patterns

Strategy: validation

Validate before calling

func fileIsTracked(path string) bool {
    return exec.Command("git", "ls-files", "--error-unmatch", path).Run() == nil
}
// call GitCheckoutFile only if fileIsTracked(path) && dirty

Try / catch

if err := GitCheckoutFile(path); err != nil {
    log.Printf("could not revert %s: %v", path, err) // git output embedded in err
    return fmt.Errorf("file not reverted, may be untracked: %w", err)
}

Prevention

When it happens

Trigger: Calling GitCheckoutFile(path) for a path that is untracked (never committed), a path that does not match any index entry, a pathspec ambiguity, or when git itself is unavailable/not in a repo.

Common situations: Trying to discard changes in a newly created (never committed) file, a typo'd or renamed path, operating outside a git repository, or the user already staged-and-committed state conflicting with expectations.

Understand the failure class

Background: "git command failed": what it means when a tool shells out to git and git exits non-zero — this error's family across 21 libraries.

Related errors


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