plandex-ai/plandex · error
Error deleting plans:
Error message
Error deleting plans:
What it means
DeleteAllPlansHandler (plans_crud.go:286) returns 500 when db.DeleteOwnerPlans(orgId, projectId, userId) fails to delete all plans owned by the user in the project. The operation is a bulk delete (DB rows plus likely per-plan directories), so the error propagates from either the SQL execution or an internal step inside DeleteOwnerPlans.
Source
Thrown at app/server/handlers/plans_crud.go:286
auth := Authenticate(w, r, true)
if auth == nil {
return
}
vars := mux.Vars(r)
projectId := vars["projectId"]
log.Println("projectId: ", projectId)
if !authorizeProject(w, projectId, auth) {
return
}
err := db.DeleteOwnerPlans(auth.OrgId, projectId, auth.User.Id)
if err != nil {
log.Printf("Error deleting plans: %v\n", err)
http.Error(w, "Error deleting plans: "+err.Error(), http.StatusInternalServerError)
return
}
log.Println("Successfully deleted all plans")
}
func ListPlansHandler(w http.ResponseWriter, r *http.Request) {
log.Println("Received request for ListPlans")
auth := Authenticate(w, r, true)
if auth == nil {
return
}
projectIds := r.URL.Query()["projectId"]
log.Println("projectIds: ", projectIds)
View on GitHub (pinned to e2d772072e)
Solutions
- Read the server log line 'Error deleting plans: <err>' to identify whether the failure is SQL-level or directory-level.
- Retry the request — if it's a transient connection issue, the retry should succeed and is idempotent for already-deleted plans.
- Check for foreign-key constraints referencing plans that block the bulk DELETE; add ON DELETE CASCADE or delete dependents first.
- For large projects, chunk the deletion or add a statement timeout and delete in batches.
Example fix
// before err := db.DeleteOwnerPlans(auth.OrgId, projectId, auth.User.Id) // after err := db.DeleteOwnerPlansBatch(ctx, auth.OrgId, projectId, auth.User.Id, 500) // delete in batches with retry
Defensive patterns
Strategy: retry
Validate before calling
if err := db.Conn.PingContext(ctx); err != nil {
return fmt.Errorf("database unavailable: %w", err)
} Type guard
func isTransientDBErr(err error) bool {
var pgErr *pgconn.PgError
return errors.As(err, &pgErr) && pgconn.SafeToRetry(err)
} Try / catch
err := db.DeleteOwnerPlans(auth.OrgId, projectId, auth.User.Id)
for i := 0; i < 3 && isTransientDBErr(err); i++ {
time.Sleep(time.Duration(1<<i) * 100 * time.Millisecond)
err = db.DeleteOwnerPlans(auth.OrgId, projectId, auth.User.Id)
} Prevention
- Retry transient DB failures with exponential backoff; the bulk delete is idempotent.
- Add FK constraints with ON DELETE CASCADE so bulk deletes are not blocked.
- Batch large deletions and set statement timeouts.
- Monitor DB pool saturation and connection errors.
When it happens
Trigger: POST/DELETE to the delete-all-plans route for a projectId where the underlying bulk DELETE statement errors — DB connection failure, SQL error in DeleteOwnerPlans, or an error deleting one of the plan directories inside the function.
Common situations: Database unavailable or connection pool exhausted; very large plan counts timing out; a single unreadable plan directory aborting the whole bulk operation; FK constraints if plans are referenced by other tables.
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 validating project
- error validating plan membership
- Error validating org membership:
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/1b9d9512155f63e8.
Report an issue: GitHub.