plandex-ai/plandex · error

Error setting plan status to replying: %v

Error message

Error setting plan status to replying: %v

What it means

At the start of execTellPlan the plan status is persisted as PlanStatusReplying via db.SetPlanStatus(planId, branch, ...). If that DB update fails, the error is logged, reported, and pushed to StreamDoneCh as a 500 ApiError "Error setting plan status to replying: %v". The plan cannot stream a reply because its persisted status could not transition.

Source

Thrown at app/server/model/plan/tell_exec.go:143

		log.Println("Executing WillExecPlanHook")
		_, apiErr := hooks.ExecHook(hooks.WillExecPlan, hooks.HookParams{
			Auth: auth,
			Plan: plan,
		})

		if apiErr != nil {
			time.Sleep(100 * time.Millisecond)
			active.StreamDoneCh <- apiErr
			return
		}
	}

	planId := plan.Id
	log.Println("execTellPlan - Setting plan status to replying")
	err := db.SetPlanStatus(planId, branch, shared.PlanStatusReplying, "")
	if err != nil {
		log.Printf("Error setting plan %s status to replying: %v\n", planId, err)
		go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error setting plan %s status to replying: %v", planId, err))

		active.StreamDoneCh <- &shared.ApiError{
			Type:   shared.ApiErrorTypeOther,
			Status: http.StatusInternalServerError,
			Msg:    fmt.Sprintf("Error setting plan status to replying: %v", err),
		}

		log.Printf("execTellPlan: execTellPlan operation completed for plan ID %s on branch %s, iteration %d\n", plan.Id, branch, iteration)
		return
	}
	log.Println("execTellPlan - Plan status set to replying")

	state := &activeTellStreamState{
		modelStreamId:       active.ModelStreamId,
		clients:             clients,
		authVars:            authVars,
		req:                 req,
		auth:                auth,

View on GitHub (pinned to e2d772072e)

Solutions

  1. Read the wrapped error in server logs to identify the DB failure mode and fix connectivity/migrations.
  2. Confirm the plan row and branch still exist in the DB (plan may have been deleted concurrently).
  3. Retry the tell request after the DB is healthy — the status write is retried per invocation.
  4. Check DB lock/timeout settings if this appears under concurrent stop/start load on the same plan.
Defensive patterns

Strategy: retry

Validate before calling

// verify DB reachable and plan exists before issuing Tell
if err := db.HealthCheck(); err != nil {
    return fmt.Errorf("db unavailable: %w", err)
}
if _, err := db.GetPlan(planId); err != nil {
    return fmt.Errorf("plan %s not found: %w", planId, err)
}

Try / catch

apiErr := <-active.StreamDoneCh
if strings.Contains(apiErr.Msg, "Error setting plan status to replying") {
    // transient DB failure: retry after backoff, plan was never set to replying
    time.Sleep(2 * time.Second)
    return retryTell(planId, branch)
}

Prevention

When it happens

Trigger: db.SetPlanStatus returns an error when execTellPlan (invoked from Tell, handleStreamFinished, or handleMissingFile) begins: DB unreachable, plan row missing (e.g. plan deleted while starting), lock contention, or invalid planId/branch combination.

Common situations: Database outage or connection-pool exhaustion at request start; user deleted/re-created the plan or branch concurrently; replica/leader DB failover mid-request; schema migration mismatch after upgrading Plandex.

Related errors


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