plandex-ai/plandex · warning

No active model stream for plan

Error message

No active model stream for plan

What it means

The lookup succeeded but returned nil: there is no active model stream row for this plan/branch. The handler returns HTTP 404 because the plan is not currently running anywhere, so there is no instance to proxy the request to. This is the expected server response when a plan has finished, errored, or was never started.

Source

Thrown at app/server/handlers/proxy_helper.go:27

	"plandex-server/db"
	"plandex-server/host"
	"time"

	shared "plandex-shared"
)

func proxyActivePlanMethod(w http.ResponseWriter, r *http.Request, planId, branch, method string) {
	modelStream, err := db.GetActiveModelStream(planId, branch)

	if err != nil {
		log.Printf("Error getting active model stream: %v\n", err)
		http.Error(w, "Error getting active model stream", http.StatusInternalServerError)
		return
	}

	if modelStream == nil {
		log.Printf("No active model stream for plan %s\n", planId)
		http.Error(w, "No active model stream for plan", http.StatusNotFound)
		return
	}

	if modelStream.InternalIp == host.Ip {
		// No active plan for this plan or else we wouldn't be calling proxyActivePlanMethod -- set the model stream to finished because something went wrong
		err := db.SetModelStreamFinished(modelStream.Id)
		if err != nil {
			log.Printf("Error setting model stream %s to finished: %v\n", modelStream.Id, err)
		}

		err = db.SetPlanStatus(planId, branch, shared.PlanStatusError, "No active stream for plan")
		if err != nil {
			log.Printf("Error setting plan %s status to error: %v\n", planId, err)
		}

		log.Printf("No active plan for plan %s\n", planId)
		http.Error(w, "No active plan for plan", http.StatusNotFound)
		return

View on GitHub (pinned to e2d772072e)

Solutions

  1. Check plan status first (or handle 404) before issuing proxied calls; refresh the plan list in the UI.
  2. Verify the planId/branch pair is current — list active plans from the DB or API.
  3. If the plan should be running, restart it and confirm its model stream row is registered (GetActiveModelStream should return a row).
  4. Make clients treat 404 here as 'plan finished' and stop polling/reconnect to a new plan.
  5. Check for clock/lifecycle bugs where SetModelStreamFinished runs earlier than expected.

Example fix

// before (client)
const res = await fetch(`/plans/${planId}/${branch}/build-status`);
// after
const res = await fetch(`/plans/${planId}/${branch}/build-status`);
if (res.status === 404) {
  ui.markPlanFinished(planId);
  return; // plan not running — don't retry
}
Defensive patterns

Strategy: type-guard

Validate before calling

// client-side: only proxy-call plans known to be active
const plan = await api.getPlan(planId);
if (!plan || plan.status !== 'running') return; // skip the proxied call

Type guard

function isActivePlan(p) { return p !== null && typeof p === 'object' && typeof p.status === 'string' && ['running','started'].includes(p.status); }

Try / catch

// client
try {
  const res = await fetch(`/plans/${planId}/${branch}/connect`);
  if (res.status === 404) {
    ui.markPlanFinished(planId); // no active stream — plan ended
    return;
  }
} catch (e) { console.error(e); }

Prevention

When it happens

Trigger: Calling ConnectPlanHandler/StopPlanHandler/RespondMissingFileHandler/AutoLoadContextHandler/GetBuildStatusHandler for a plan whose model stream already finished or errored; plan ID typo or from a previous session; plan created but its instance never registered a stream; server restarted and in-memory/stream rows were cleared.

Common situations: User leaves a tab open after the plan completes and the page still polls build status; client retries an old planId after redeployment; race where the plan just finished between status check and the proxied call; pointing the client at a different environment's plans.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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