plandex-ai/plandex · critical

error setting plan status to building: %v

Error message

error setting plan status to building: %v

What it means

Build sets the plan's status to PlanStatusBuilding before queueing pending builds. If db.SetPlanStatus fails, it logs the cause, invokes the onErr handler, and returns "error setting plan status to building: %v". The build is aborted because a stale/unknown status would break downstream state transitions.

Source

Thrown at app/server/model/plan/build_exec.go:83

		return 0, err
	}

	pendingBuildsByPath, err := state.loadPendingBuilds(sessionId)
	if err != nil {
		return onErr(err)
	}

	if len(pendingBuildsByPath) == 0 {
		log.Println("No pending builds")
		streamDone()
		return 0, nil
	}

	err = db.SetPlanStatus(plan.Id, branch, shared.PlanStatusBuilding, "")

	if err != nil {
		log.Printf("Error setting plan status to building: %v\n", err)
		return onErr(fmt.Errorf("error setting plan status to building: %v", err))
	}

	log.Printf("Starting %d builds\n", len(pendingBuildsByPath))

	for _, pendingBuilds := range pendingBuildsByPath {
		go state.queueBuilds(pendingBuilds)
	}

	return len(pendingBuildsByPath), nil
}

func (state *activeBuildStreamState) queueBuild(activeBuild *types.ActiveBuild) {
	planId := state.plan.Id
	branch := state.branch

	filePath := activeBuild.Path

	// log.Printf("Queue:")

View on GitHub (pinned to e2d772072e)

Solutions

  1. Fix the underlying DB issue surfaced in the wrapped %v message (connectivity, auth, schema).
  2. Verify the plan row for that ID/branch still exists before building.
  3. Retry transient DB failures with backoff before invoking onErr.
  4. Run pending migrations to ensure the plan status columns match the code.

Example fix

// before: single attempt
err = db.SetPlanStatus(plan.Id, branch, shared.PlanStatusBuilding, "")
if err != nil { return onErr(fmt.Errorf(...)) }
// after: retry transient errors
err = retryTransient(3, func() error { return db.SetPlanStatus(plan.Id, branch, shared.PlanStatusBuilding, "") })
if err != nil { return onErr(fmt.Errorf("error setting plan status to building: %v", err)) }
Defensive patterns

Strategy: retry

Validate before calling

plan, err := db.GetPlan(planId)
if err != nil || plan == nil {
    return fmt.Errorf("plan %s missing before build; skip status update", planId)
}

Try / catch

err := Build(ctx, plan, branch)
if err != nil && strings.Contains(err.Error(), "error setting plan status to building") {
    time.Sleep(time.Second)
    err = Build(ctx, plan, branch) // retry transient DB failure
}

Prevention

When it happens

Trigger: db.SetPlanStatus(plan.Id, branch, PlanStatusBuilding, "") returns an error: DB connection failure, transaction timeout, missing plan/branch row (plan deleted between checks), or schema mismatch.

Common situations: DB unreachable during a deploy, plan row removed by a concurrent delete, migration lag, or file/sqlite DB lock contention under heavy concurrent builds.

Related errors


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