plandex-ai/plandex · error
error loading plan: %v
Error message
error loading plan: %v
What it means
Aggregation error in tell_load.go: after launching four parallel loader goroutines (convo/store message, plan summaries, plan subtasks, settings), the parent collects four results from errCh; the first non-nil is reported as 'error loading plan: %v', sent to Sentry-like notify, and pushed to the client as a 500 ApiError on StreamDoneCh. It is the umbrella for any of the child load errors (740-742 etc.).
Source
Thrown at app/server/model/plan/tell_load.go:314
errCh <- fmt.Errorf("error getting plan subtasks: %v\n%s", r, debug.Stack())
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
res, err := db.GetPlanSubtasks(auth.OrgId, planId)
if err != nil {
log.Printf("Error getting plan subtasks: %v\n", err)
errCh <- fmt.Errorf("error getting plan subtasks: %v", err)
return
}
subtasks = res
errCh <- nil
}()
for i := 0; i < 4; i++ {
err = <-errCh
if err != nil {
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error loading plan: %v", err))
active.StreamDoneCh <- &shared.ApiError{
Type: shared.ApiErrorTypeOther,
Status: http.StatusInternalServerError,
Msg: fmt.Sprintf("Error loading plan: %v", err),
}
return err
}
}
res, err := db.GetCurrentPlanState(db.CurrentPlanStateParams{
OrgId: currentOrgId,
PlanId: planId,
Contexts: modelContext,
})
if err != nil {
return fmt.Errorf("error getting current plan state: %v", err)View on GitHub (pinned to e2d772072e)
Solutions
- Read the wrapped child error after 'error loading plan:' to find the root cause
- Check the server log lines just before it (the child goroutines log their own errors)
- Verify database health and migrations
- Retry the plan load once the underlying issue is fixed
Defensive patterns
Strategy: try-catch
Validate before calling
if planId == "" {
active.StreamDoneCh <- &shared.ApiError{Type: shared.ApiErrorTypeOther, Status: http.StatusBadRequest, Msg: "missing planId"}
return fmt.Errorf("missing planId")
} Try / catch
for i := 0; i < 4; i++ {
err = <-errCh
if err != nil {
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error loading plan: %w", err))
active.StreamDoneCh <- &shared.ApiError{Type: shared.ApiErrorTypeOther, Status: http.StatusInternalServerError, Msg: fmt.Sprintf("Error loading plan: %v", err)}
return err
}
} Prevention
- Always send exactly one nil-or-error per loader goroutine on errCh
- Log child errors before wrapping so the root cause is traceable
- Add DB health monitoring to catch outages early
- Consider context cancellation to avoid orphaned goroutines after first error
When it happens
Trigger: Any of the four loader goroutines sends a non-nil error: failed user-message store, GetPlanSummaries error, GetPlanSubtasks error (including recovered panics), or a settings load failure.
Common situations: DB outage during plan load; one of the child queries failing due to schema drift or a race; plan deleted mid-load so a child query fails.
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 committing convo message: %v
- error accepting invite: %v
- panic in SyncPlanTokens: %v %s
- error getting contexts or convo: %v
- failed to get DB lock: %w
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/f5db249b1c7dff8d.
Report an issue: GitHub.