plandex-ai/plandex · error

error getting plan modelContext: %v

Error message

error getting plan modelContext: %v

What it means

During loadPendingBuilds, Plandex fetches plan contexts (including the plan modelContext) in a background goroutine inside a repo read lock. If db.GetPlanContexts returns an error, or the goroutine panics, the failure is formatted as "error getting plan modelContext: %v" and sent to errCh, aborting the load. A panic-origin message (via the recover block) indicates a runtime crash inside the context fetch; otherwise it's the raw database error.

Source

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

	var orgUserConfig *shared.OrgUserConfig

	err = db.ExecRepoOperation(db.ExecRepoOperationParams{
		OrgId:    auth.OrgId,
		UserId:   auth.User.Id,
		PlanId:   plan.Id,
		Branch:   branch,
		Scope:    db.LockScopeRead,
		Ctx:      active.Ctx,
		CancelFn: active.CancelFn,
		Reason:   "load pending builds",
	}, func(repo *db.GitRepo) error {
		errCh := make(chan error, 4)

		go func() {
			defer func() {
				if r := recover(); r != nil {
					log.Printf("panic in getPlanContexts: %v\n%s", r, debug.Stack())
					errCh <- fmt.Errorf("error getting plan modelContext: %v", r)
					runtime.Goexit() // don't allow outer function to continue and double-send to channel
				}
			}()
			res, err := db.GetPlanContexts(auth.OrgId, plan.Id, true, false)
			if err != nil {
				log.Printf("Error getting plan modelContext: %v\n", err)
				errCh <- fmt.Errorf("error getting plan modelContext: %v", err)
				return
			}
			modelContext = res

			errCh <- nil
		}()

		go func() {
			defer func() {
				if r := recover(); r != nil {
					log.Printf("panic in getPlanSettings: %v\n%s", r, debug.Stack())

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check the server log for the companion line "Error getting plan modelContext: ..." or "panic in getPlanContexts" with its stack trace to separate DB errors from panics
  2. Verify database connectivity and that the plan's context rows exist and are uncorrupted
  3. If a panic occurred, use the printed debug.Stack() to identify and fix the offending code or report it upstream
  4. Retry the plan load if the DB error was transient (restart, failover, network blip)
  5. Confirm org/plan IDs are valid and consistent — manual DB modifications or failed migrations can leave contexts unreadable
Defensive patterns

Strategy: validation

Validate before calling

// before loading pending builds, confirm plan/org exist and DB is reachable
if _, err := db.GetPlan(auth.OrgId, plan.Id); err != nil {
	return fmt.Errorf("plan not loadable before pending-build fetch: %v", err)
}
if err := db.Ping(); err != nil {
	return fmt.Errorf("database unreachable: %v", err)
}

Try / catch

// collect the error from errCh (buffered, 4 slots) and inspect
err := <-errCh
if err != nil {
	if strings.Contains(err.Error(), "panic") || strings.Contains(err.Error(), "runtime error") {
		log.Printf("panic-driven context load failure: %v", err) // stack is in server logs
	} else {
		log.Printf("db failure loading plan context: %v", err) // retry on transient errors
	}
	return err
}

Prevention

When it happens

Trigger: db.GetPlanContexts(auth.OrgId, plan.Id, true, false) failing — DB connection error, missing/corrupt context rows for the plan, or a panic inside the goroutine caught by the recover() in build_load.go:50-55.

Common situations: Postgres unavailable or connection pool exhausted at plan load time; a nil-pointer panic in the context-loading code path (check for the "panic in getPlanContexts" log with a stack trace); org/plan IDs inconsistent after a failed migration or manual DB edit; network partition between server and database.

Related errors


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