plandex-ai/plandex · error
Error getting branches:
Error message
Error getting branches:
What it means
ListBranchesHandler wraps the branch listing (db.ListPlanBranches under a read-locked repo operation) and returns HTTP 500 with 'Error getting branches: <err>' when that operation fails. This is a server-side catch-all covering git repo access and database query failures while enumerating a plan's branches. The underlying error text is appended so the client can see the real cause.
Source
Thrown at app/server/handlers/branches.go:63
Reason: "list branches",
Scope: db.LockScopeRead,
Ctx: ctx,
CancelFn: cancel,
}, func(repo *db.GitRepo) error {
res, err := db.ListPlanBranches(repo, planId)
if err != nil {
return err
}
branches = res
return nil
})
if err != nil {
log.Printf("Error getting branches: %v\n", err)
http.Error(w, "Error getting branches: "+err.Error(), http.StatusInternalServerError)
return
}
jsonBytes, err := json.Marshal(branches)
if err != nil {
log.Printf("Error marshalling branches: %v\n", err)
http.Error(w, "Error marshalling branches: "+err.Error(), http.StatusInternalServerError)
return
}
log.Println("Successfully retrieved branches")
w.Write(jsonBytes)
}
func CreateBranchHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Received request for CreateBranchHandler")View on GitHub (pinned to e2d772072e)
Solutions
- Check server logs for the wrapped underlying error to see whether it was a lock timeout, git error, or DB error
- Verify the plan's git repo directory exists on the server volume and is not corrupted (git fsck)
- Confirm the database is reachable and connections are not exhausted
- Retry after in-flight write operations on the plan complete (locks are released)
Example fix
// before
branches, err := db.ListPlanBranches(repo, planId)
if err != nil { return err }
// after
branches, err := db.ListPlanBranches(repo, planId)
if err != nil {
return fmt.Errorf("list plan branches: %w", err) // preserves context for the 500 body
} Defensive patterns
Strategy: retry
Validate before calling
// client: verify plan exists and is accessible before listing branches
resp, _ := client.Get(planURL)
if resp.StatusCode == 404 { return errors.New("plan not found; fix planId") } Try / catch
// retry with backoff on 500, since lock contention is transient
for i := 0; i < 3; i++ {
resp, err := client.Get(branchesURL)
if err == nil && resp.StatusCode == 200 { break }
if resp != nil && resp.StatusCode < 500 { return err } // non-retryable
time.Sleep(time.Duration(1<<i) * time.Second)
} Prevention
- Avoid running conflicting plan operations concurrently on the same plan
- Monitor plan repo volume health and disk space
- Alert on database connection pool saturation
- Surface the wrapped error body to diagnose lock vs DB vs git causes
When it happens
Trigger: GET to the plan branches endpoint when: the plan's git repo is missing or corrupted, the database query for branches fails (connection dropped, table locked), the read lock on 'main' cannot be acquired before context cancellation, or the repo lock times out because another operation holds a write lock.
Common situations: Hitting the endpoint while another long-running plan operation holds the repo write lock; a crashed/plans volume missing so the git repo dir doesn't exist; Postgres restarted or maxing connections; planId pointing to a deleted plan whose repo was pruned.
Related errors
- Error creating branch:
- Error deleting branch:
- Error getting plan diffs:
- error invalidating conflicted results: %v
- error committing convo message: %v
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/ed258d19511bf8ed.
Report an issue: GitHub.