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

  1. Use the logged stack trace (debug.Stack output) to find the panicking line
  2. Inspect the result JSON files for the plan and fix/remove corrupt entries
  3. Update the db package to a version where the panicking bug is fixed
  4. Call GetFullCurrentPlanStateParams in a wrapper that retries once after validating storage
  5. 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

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


AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05). Data as JSON: /api/errors/49fe62fd9d50d7d1. Report an issue: GitHub.