plandex-ai/plandex · error
error getting plan summaries: %v
Error message
error getting plan summaries: %v
What it means
This error is produced by the getPlanSummaries goroutine's recover handler: the goroutine that loads the plan's conversation summaries panicked. The recovered value is wrapped and sent on innerErrCh so loadTellPlan aborts cleanly rather than crashing the server.
Source
Thrown at app/server/model/plan/tell_load.go:246
if err != nil {
log.Printf("[TellLoad] Error storing user message: %v\n", err)
innerErrCh <- fmt.Errorf("error storing user message: %v", err)
return
}
UpdateActivePlan(planId, branch, func(ap *types.ActivePlan) {
ap.MessageNum = num
})
}
innerErrCh <- nil
}()
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in getPlanSummaries: %v\n%s", r, debug.Stack())
innerErrCh <- fmt.Errorf("error getting plan summaries: %v", r)
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
var convoMessageIds []string
for _, convoMessage := range convo {
convoMessageIds = append(convoMessageIds, convoMessage.Id)
}
log.Println("getting plan summaries")
log.Println("convoMessageIds:", convoMessageIds)
res, err := db.GetPlanSummaries(planId, convoMessageIds)
if err != nil {
log.Printf("Error getting plan summaries: %v\n", err)
innerErrCh <- fmt.Errorf("error getting plan summaries: %v", err)
returnView on GitHub (pinned to e2d772072e)
Solutions
- Inspect the 'panic in getPlanSummaries' stack trace to find the exact deref site
- Skip convo messages with empty/nil Ids when building convoMessageIds
- Validate GetPlanSummaries results before indexing summaries[len-1]
- Run with -race to check for concurrent mutation of the shared convo slice
Example fix
// before
for _, convoMessage := range convo {
convoMessageIds = append(convoMessageIds, convoMessage.Id)
}
// after
for _, convoMessage := range convo {
if convoMessage.Id != "" {
convoMessageIds = append(convoMessageIds, convoMessage.Id)
}
} Defensive patterns
Strategy: type-guard
Validate before calling
if len(convo) == 0 {
log.Println("no convo messages; skipping summaries fetch")
return nil
}
for _, m := range convo {
if m.Id == "" {
return fmt.Errorf("convo message missing Id; cannot fetch summaries safely")
}
} Type guard
func hasValidConvoIds(convo []db.ConvoMessage) bool {
for _, m := range convo {
if m.Id == "" {
return false
}
}
return true
} Try / catch
if err := <-innerErrCh; err != nil && strings.HasPrefix(err.Error(), "error getting plan summaries:") {
// panic-recovery path — stack already logged; proceed with empty summaries or abort
return err
} Prevention
- Filter out convo entries with empty Ids before building convoMessageIds
- Never mutate the shared convo slice from other goroutines while summaries load
- Bounds-check summaries before accessing the last element
- Keep the defer/recover wrapper on every goroutine sending to innerErrCh
When it happens
Trigger: A panic inside the goroutine guarded at tell_load.go:246 — e.g., nil dereference while building convoMessageIds from convo entries with nil pointers, or a panic inside db.GetPlanSummaries(planId, convoMessageIds) or while reading the last summary's .Summary field.
Common situations: Corrupted convo entries with missing Ids or nil fields in the DB; convo slice mutated concurrently by another goroutine; nil summaries entry accessed via summaries[len-1].Summary after a partial query result.
Related errors
- error getting plan convo: %v
- error storing user message: %v
- error getting org user config: %v
- error getting plan subtasks: %v %s
- panic in UpdateContexts: %v\n%s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a77493607ccb4570.
Report an issue: GitHub.