plandex-ai/plandex · error

error getting plan applies: %v

Error message

error getting plan applies: %v

What it means

GetCurrentPlanState fetches plan applies in a worker goroutine via GetPlanApplies(orgId, planId). A non-nil error from that call is re-wrapped here as 'error getting plan applies: %v' and sent to errCh, aborting the full plan-state load and returning this error to the caller.

Source

Thrown at app/server/db/result_helpers.go:242

			if context.FilePath != "" {
				contextsByPath[context.FilePath] = context
			}
		}

		errCh <- nil
	}()

	go func() {
		defer func() {
			if r := recover(); r != nil {
				log.Printf("panic in GetCurrentPlanState: %v\n%s", r, debug.Stack())
				errCh <- fmt.Errorf("panic in GetCurrentPlanState: %v\n%s", r, debug.Stack())
				runtime.Goexit() // don't allow outer function to continue and double-send to channel
			}
		}()
		res, err := GetPlanApplies(orgId, planId)
		if err != nil {
			errCh <- fmt.Errorf("error getting plan applies: %v", err)
			return
		}

		for _, apply := range res {
			planApplies = append(planApplies, apply.ToApi())
		}

		errCh <- nil
	}()

	for i := 0; i < 4; i++ {
		err := <-errCh
		if err != nil {
			return nil, err
		}
	}

	var apiPlanFileResults []*shared.PlanFileResult

View on GitHub (pinned to e2d772072e)

Solutions

  1. Inspect the wrapped inner error to distinguish permissions vs missing storage vs backend failure
  2. Verify the plan's applies storage exists and is readable by the server process
  3. Correct orgId/planId if data was copied between environments
  4. Restore or recreate the missing applies data from backup
  5. Retry if the inner error indicates a transient backend issue

Example fix

// before
res, err := GetPlanApplies(orgId, planId)
if err != nil {
    return nil, err
}
// after
res, err := GetPlanApplies(orgId, planId)
if err != nil {
    log.Printf("plan applies unavailable for %s/%s: %v; continuing without applies", orgId, planId, err)
    res = nil
}
Defensive patterns

Strategy: retry

Validate before calling

if _, err := GetPlanApplies(orgId, planId); err != nil {
    if !os.IsNotExist(err) {
        // transient-looking failure; back off before calling GetCurrentPlanState
        time.Sleep(500 * time.Millisecond)
    }
}

Type guard

func isPlanAppliesError(err error) bool {
    return err != nil && strings.Contains(err.Error(), "error getting plan applies")
}

Try / catch

var planState *shared.CurrentPlanState
var err error
for attempt := 0; attempt < 3; attempt++ {
    planState, err = GetCurrentPlanState(params)
    if err == nil || !isPlanAppliesError(err) {
        break
    }
    time.Sleep(time.Duration(attempt+1) * 500 * time.Millisecond)
}

Prevention

When it happens

Trigger: Calling GetCurrentPlanState when the plan-applies storage read fails for the org/plan — e.g. missing applies directory (non-NotExist error), permissions problem, or underlying query failure inside GetPlanApplies.

Common situations: Plan storage partially deleted (applies removed but plan metadata remains); running the server with a user lacking read access to the applies path; transient storage backend errors during high load; org/plan id mismatch after an environment copy.

Related errors


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