plandex-ai/plandex · error
Error listing plans:
Error message
Error listing plans:
What it means
ListPlansHandler (plans_crud.go:339) returns 500 when db.ListOwnedPlans(authorizedProjectIds, userId, false) fails to query the user's plans for the authorized projects. The error originates in the database layer — connection failure, SQL error, or scan error while reading rows.
Source
Thrown at app/server/handlers/plans_crud.go:339
}
authorizedProjectIds := []string{}
for _, projectId := range projectIds {
if authorizeProjectOptional(w, projectId, auth, false) {
authorizedProjectIds = append(authorizedProjectIds, projectId)
}
}
if len(authorizedProjectIds) == 0 {
writePlans()
return
}
plans, err := db.ListOwnedPlans(authorizedProjectIds, auth.User.Id, false)
if err != nil {
log.Printf("Error listing plans: %v\n", err)
http.Error(w, "Error listing plans: "+err.Error(), http.StatusInternalServerError)
return
}
for _, plan := range plans {
apiPlans = append(apiPlans, plan.ToApi())
}
writePlans()
}
func ListArchivedPlansHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Received request for ListArchivedPlansHandler")
auth := Authenticate(w, r, true)
if auth == nil {
return
}
projectIds := r.URL.Query()["projectId"]View on GitHub (pinned to e2d772072e)
Solutions
- Check the server log 'Error listing plans: <err>' for the underlying DB error and fix accordingly.
- Verify DB connectivity/pool health (max connections, idle timeouts) and that the DB is running.
- Confirm the plans schema matches the deployed code — run pending migrations.
- Retry the request for transient failures; add automatic retry with backoff for idempotent reads.
Example fix
// before
plans, err := db.ListOwnedPlans(authorizedProjectIds, auth.User.Id, false)
// after
plans, err := db.ListOwnedPlans(authorizedProjectIds, auth.User.Id, false)
if err != nil {
if isTransient(err) { // e.g. pgconn.SafeToRetry
plans, err = db.ListOwnedPlans(authorizedProjectIds, auth.User.Id, false)
}
} Defensive patterns
Strategy: retry
Validate before calling
if len(authorizedProjectIds) == 0 { return } // caller already guards this before querying
if err := db.Conn.PingContext(ctx); err != nil { return err } Type guard
func isTransientDBErr(err error) bool {
var pgErr *pgconn.PgError
return errors.As(err, &pgErr) && pgconn.SafeToRetry(err)
} Try / catch
plans, err := db.ListOwnedPlans(ids, userId, false)
if err != nil {
if isTransientDBErr(err) {
plans, err = db.ListOwnedPlans(ids, userId, false) // one bounded retry
}
if err != nil {
http.Error(w, "Error listing plans", http.StatusInternalServerError)
return
}
} Prevention
- Apply DB migrations before deploying schema-dependent code.
- Monitor pool saturation; size max connections for read-heavy list endpoints.
- Retry idempotent reads on transient errors with backoff.
- Alert on database connection/error rate from handler logs.
When it happens
Trigger: GET /plans?projectId=... with at least one authorized projectId, and the ListOwnedPlans SQL query fails: DB unreachable, connection pool exhausted, invalid query after a schema migration (renamed columns/table), or row-scan type mismatch.
Common situations: Database restart or network blip; deploying code against a mismatched schema (migration not applied); connection pool exhaustion under load; listing plans for many projects producing a query timeout.
Understand the failure class
Background: Database query failed: Internal Server Error 500s wrapping SQL, Prisma, and connection failures — what to check first — this error's family across 16 libraries.
Related errors
- error getting current plan state params: %v
- error getting contexts: %v
- error getting plan convo: %v
- error validating project
- error validating plan membership
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/b4f9c27eb0e778cb.
Report an issue: GitHub.