plandex-ai/plandex · error
panic in GetFullCurrentPlanStateParams: %v\n%s
Error message
panic in GetFullCurrentPlanStateParams: %v\n%s
What it means
GetFullCurrentPlanStateParams fans out three goroutines, each guarded by a defer/recover. If the goroutine that calls GetPlanFileResults panics, the panic is captured, logged with a stack trace, converted into this error, and sent on errCh so the caller receives it instead of the process crashing.
Source
Thrown at app/server/db/result_helpers.go:75
OrgId string
PlanId string
PlanFileResults []*PlanFileResult
ConvoMessageDescriptions []*ConvoMessageDescription
Contexts []*Context
}
func GetFullCurrentPlanStateParams(orgId, planId string) (CurrentPlanStateParams, error) {
errCh := make(chan error, 3)
var results []*PlanFileResult
var convoMessageDescriptions []*ConvoMessageDescription
var contexts []*Context
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in GetFullCurrentPlanStateParams: %v\n%s", r, debug.Stack())
errCh <- fmt.Errorf("panic in GetFullCurrentPlanStateParams: %v\n%s", r, debug.Stack())
runtime.Goexit() // don't allow outer function to continue and double-send to channel
}
}()
res, err := GetPlanFileResults(orgId, planId)
if err != nil {
errCh <- fmt.Errorf("error getting plan file results: %v", err)
return
}
results = res
errCh <- nil
}()
go func() {
defer func() {
if r := recover(); r != nil {
log.Printf("panic in GetFullCurrentPlanStateParams: %v\n%s", r, debug.Stack())
errCh <- fmt.Errorf("panic in GetFullCurrentPlanStateParams: %v\n%s", r, debug.Stack())View on GitHub (pinned to e2d772072e)
Solutions
- Use the logged stack trace (debug.Stack output) to find the panicking line
- Inspect the result JSON files for the plan and fix/remove corrupt entries
- Update the db package to a version where the panicking bug is fixed
- Call GetFullCurrentPlanStateParams in a wrapper that retries once after validating storage
- Report/reproduce with the same orgId/planId and dump the results directory contents
Example fix
// before
params, err := db.GetFullCurrentPlanStateParams(orgId, planId)
// after
params, err := db.GetFullCurrentPlanStateParams(orgId, planId)
if err != nil && strings.Contains(err.Error(), "panic in GetFullCurrentPlanStateParams") {
log.Printf("panic while loading plan state for %s/%s: %v", orgId, planId, err)
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate storage readability before calling
if _, err := db.GetPlanFileResults(orgId, planId); err != nil {
return fmt.Errorf("plan results storage unhealthy: %w", err)
} Type guard
func isPanicError(err error) bool {
return err != nil && strings.Contains(err.Error(), "panic in ")
} Try / catch
params, err := db.GetFullCurrentPlanStateParams(orgId, planId)
if isPanicError(err) {
log.Printf("internal panic loading plan state (see server stack trace): %v", err)
return nil, err
} Prevention
- Keep the server log alongside this error — the stack trace is included in the message
- Avoid hand-editing result JSON files under the plans data dir
- Run integration tests against representative stored data after upgrades
- Pin db package versions and read changelogs for concurrency fixes
- Call with distinct orgId/planId to isolate whether corruption is plan-specific
When it happens
Trigger: A panic inside the first worker goroutine while fetching plan file results — typically nil map/slice access or a nil pointer dereference on corrupted result data inside GetPlanFileResults.
Common situations: Corrupt or hand-edited JSON result files triggering unexpected code paths; a nil receiver bug introduced in db helpers after an upgrade; out-of-range index on malformed stored results.
Related errors
- panic in UpdateContexts: %v\n%s
- panic in GetPlanConvo: %v\n%s
- panic in gitRemoveIndexLockFileIfExists: %v %s
- panic in DeleteDraftPlans: %v %s
- panic in GetCurrentPlanState: %v\n%s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/49fe62fd9d50d7d1.
Report an issue: GitHub.