plandex-ai/plandex · error

error getting plan current branch: %v

Error message

error getting plan current branch: %v

What it means

GetCurrentBranchNamesByPlanId fans out one goroutine per planId, each calling getPlanCurrentBranch. When any goroutine gets an error, it wraps it as 'error getting plan current branch: %v' and the collector loop returns it, aborting the whole batch lookup. It is an aggregate wrapper — the root cause is always an inner error from getPlanCurrentBranch (unset config, missing project, file read/parse failure).

Source

Thrown at app/cli/lib/plans.go:180

}

func GetCurrentBranchNamesByPlanId(planIds []string) (map[string]string, error) {
	if fs.HomePlandexDir == "" {
		return nil, fmt.Errorf("HomePlandexDir not set")
	}

	if CurrentProjectId == "" || HomeCurrentPlanPath == "" {
		return nil, fmt.Errorf("no current project")
	}

	var mu sync.Mutex
	branches := make(map[string]string)
	errCh := make(chan error, len(planIds))
	for _, planId := range planIds {
		go func(planId string) {
			branch, err := getPlanCurrentBranch(planId)
			if err != nil {
				errCh <- fmt.Errorf("error getting plan current branch: %v", err)
			} else {
				mu.Lock()
				defer mu.Unlock()
				branches[planId] = branch
				errCh <- nil
			}
		}(planId)
	}

	for i := 0; i < len(planIds); i++ {
		err := <-errCh
		if err != nil {
			return nil, err
		}
	}

	return branches, nil
}

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped '%v' suffix to identify the true inner error and fix that first
  2. Run 'plandex init' or open a valid project so fs.HomePlandexDir, CurrentProjectId and HomeCurrentPlanPath are set
  3. Delete or repair the malformed/unreadable settings-v2.json for the offending plan (missing file is fine — it defaults to 'main')
  4. Check file permissions on the settings-v2.json path under HomePlandexDir

Example fix

// before
branches, err := GetCurrentBranchNamesByPlanId(ids)
// after
if fs.HomePlandexDir == "" || CurrentProjectId == "" {
    return fmt.Errorf("initialize plandex project first: %w", err)
}
branches, err := GetCurrentBranchNamesByPlanId(ids)
Defensive patterns

Strategy: try-catch

Validate before calling

if fs.HomePlandexDir == "" || CurrentProjectId == "" || HomeCurrentPlanPath == "" {
    return fmt.Errorf("plandex not initialized: set home dir and open a project first")
}
for _, id := range planIds {
    if _, err := os.Stat(filepath.Join(fs.HomePlandexDir, CurrentProjectId, id, "settings-v2.json")); err != nil && !os.IsNotExist(err) {
        return fmt.Errorf("plan %s settings unreachable: %w", id, err)
    }
}

Type guard

func hasProjectContext() bool {
    return fs.HomePlandexDir != "" && CurrentProjectId != "" && HomeCurrentPlanPath != ""
}

Try / catch

branches, err := GetCurrentBranchNamesByPlanId(planIds)
if err != nil {
    if strings.Contains(err.Error(), "HomePlandexDir not set") || strings.Contains(err.Error(), "no current project") {
        // re-initialize / open project, then retry once
    } else {
        return fmt.Errorf("branch lookup failed: %w", err)
    }
}

Prevention

When it happens

Trigger: Calling GetCurrentBranchNamesByPlanId(planIds) when any plan's settings-v2.json cannot be read or parsed, or package-level globals fs.HomePlandexDir / CurrentProjectId / HomeCurrentPlanPath are empty.

Common situations: Running the CLI before Plandex home dir or current project was initialized; a corrupt or hand-edited settings-v2.json; permissions problems under ~/.plandex; asking for branch names of plans from another project.

Related errors


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