plandex-ai/plandex · error

error getting current plan state: %v

Error message

error getting current plan state: %v

What it means

Inside loadBuildFile, the goroutine that calls db.GetCurrentPlanState is wrapped in a recover() defer. If that goroutine panics, the panic value r is logged with a stack trace, converted to an error via fmt.Errorf("error getting current plan state: %v", r), and sent to errCh; then runtime.Goexit() stops the goroutine so it cannot double-send. This error therefore means the plan-state fetch crashed (nil pointer, index out of range, etc.) rather than returning a normal db error.

Source

Thrown at app/server/model/plan/build_load.go:239

	err = db.ExecRepoOperation(db.ExecRepoOperationParams{
		OrgId:       currentOrgId,
		UserId:      state.activeBuildStreamState.currentUserId,
		PlanId:      planId,
		Branch:      branch,
		PlanBuildId: build.Id,
		Scope:       db.LockScopeRead,
		Ctx:         activePlan.Ctx,
		CancelFn:    activePlan.CancelFn,
		Reason:      "load build file",
	}, func(repo *db.GitRepo) error {
		errCh := make(chan error, 2)

		go func() {
			defer func() {
				if r := recover(); r != nil {
					log.Printf("panic in getCurrentPlanState: %v\n%s", r, debug.Stack())
					errCh <- fmt.Errorf("error getting current plan state: %v", r)
					runtime.Goexit() // don't allow outer function to continue and double-send to channel
				}
			}()
			log.Println("loadBuildFile - Getting current plan state")
			res, err := db.GetCurrentPlanState(db.CurrentPlanStateParams{
				OrgId:  currentOrgId,
				PlanId: planId,
			})
			if err != nil {
				log.Printf("Error getting current plan state: %v\n", err)
				UpdateActivePlan(activePlan.Id, activePlan.Branch, func(ap *types.ActivePlan) {
					ap.IsBuildingByPath[filePath] = false
				})
				go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error getting current plan state: %v", err))

				activePlan.StreamDoneCh <- &shared.ApiError{
					Type:   shared.ApiErrorTypeOther,
					Status: http.StatusInternalServerError,

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the goroutine's panic stack trace printed just before this error for the exact nil-deref/bounds line in db.GetCurrentPlanState
  2. Verify the plan state record for the given OrgId/PlanId is not corrupt or null-shaped (missing expected nested fields)
  3. Harden db.GetCurrentPlanState against missing/nil nested structures before use
  4. Re-run the build load after fixing; the plan is unlocked and IsBuildingByPath reset in the outer error path

Example fix

// before
res, err := db.GetCurrentPlanState(db.CurrentPlanStateParams{OrgId: currentOrgId, PlanId: planId}) // panics on nil state
// after
if currentOrgId == "" || planId == "" {
	errCh <- fmt.Errorf("error getting current plan state: missing orgId or planId")
	return
}
res, err := db.GetCurrentPlanState(db.CurrentPlanStateParams{OrgId: currentOrgId, PlanId: planId})
Defensive patterns

Strategy: try-catch

Validate before calling

if currentOrgId == "" || planId == "" {
	return fmt.Errorf("orgId and planId are required")
}

Type guard

func hasPlanStateParams(orgId, planId string) bool { return orgId != "" && planId != "" }

Try / catch

res, err := safeGetCurrentPlanState(currentOrgId, planId)
if err != nil {
	log.Printf("plan state unavailable: %v", err)
	return err
}

Prevention

When it happens

Trigger: A panic occurs inside the goroutine running db.GetCurrentPlanState(db.CurrentPlanStateParams{OrgId, PlanId}) during loadBuildFile — e.g. nil deref or out-of-range access in the db layer while loading plan state for the org/plan.

Common situations: Corrupt or unexpected plan state data in the store triggering a nil map/slice access in db.GetCurrentPlanState; concurrent mutation of ActivePlan state while the load runs; a bug in a recently changed db helper invoked by GetCurrentPlanState.

Related errors


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