plandex-ai/plandex · warning
No active plan for plan
Error message
No active plan for plan
What it means
A model stream row exists, but the plan is not in a running state (modelStream.Status is not running/started as expected), so the handler treats the plan as dead: it marks the plan status as error via SetPlanStatus and returns HTTP 404 "No active plan for plan". This is a lifecycle-mismatch guard — the stream record is stale relative to the plan's actual state.
Source
Thrown at app/server/handlers/proxy_helper.go:44
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
} else {
log.Printf("Forwarding request to %s\n", modelStream.InternalIp)
proxyUrl := fmt.Sprintf("http://%s:%s/plans/%s/%s/%s", modelStream.InternalIp, os.Getenv("PORT"), planId, branch, method)
proxyUrl += "?proxy=true"
log.Printf("Proxy url: %s\n", proxyUrl)
proxyRequest(w, r, proxyUrl)
return
}
}
func proxyRequest(w http.ResponseWriter, originalRequest *http.Request, url string) {
client := &http.Client{
Timeout: time.Second * 10,
}
// Create a new request based on the original requestView on GitHub (pinned to e2d772072e)
Solutions
- The plan was marked error server-side — refresh plan status via the status endpoint and start a new plan run.
- Check server logs for why the plan stopped (instance crash, OOM, manual stop) and fix the root cause.
- Harden the instance lifecycle so SetModelStreamFinished/SetPlanStatus always run on shutdown (defer, signal handlers, health-check-driven cleanup).
- Clients should handle 404 by abandoning the old plan and creating/reconnecting a fresh one.
- Verify planId+branch match the actually-running plan to avoid hitting stale rows.
Example fix
// before (client)
await connectToPlan(planId, branch); // throws on 404 after a crash
// after
try {
await connectToPlan(planId, branch);
} catch (e) {
if (e.status === 404) {
await startNewPlan(planId, branch); // stale/errored plan: restart
} else {
throw e;
}
} Defensive patterns
Strategy: fallback
Validate before calling
// client-side: check status before proxied calls
const plan = await api.getPlan(planId, branch);
if (!plan || plan.status !== 'running') { await startNewPlan(planId, branch); return; } Try / catch
// client fallback
try {
await connectToPlan(planId, branch);
} catch (e) {
if (e.status === 404) {
// server marked plan errored — fall back to a fresh run
await startNewPlan(planId, branch);
} else { throw e; }
} Prevention
- Ensure instances run cleanup (SetModelStreamFinished / SetPlanStatus) on shutdown via signal handlers and defers.
- Monitor instance crashes (OOM, node reclaim) that leave stale stream rows.
- Verify planId+branch correctness to avoid resolving stale rows.
- Add a reconciler that marks streams error/finished when heartbeats stop.
When it happens
Trigger: Plan crashed or its instance died without a clean SetModelStreamFinished, leaving a non-running stream row; user hits a proxied endpoint for a plan that errored; status column updated by another component while the stream row remained; branch mismatch so the lookup returns a stale row for a different run.
Common situations: Instance OOM-killed or node reclaimed, no cleanup ran; deploys restarting instances mid-plan; client polling a finished/errored plan after a crash; concurrent stop requests racing with the status update.
Related errors
- No active model stream for plan
- org not found
- error updating context: %v
- LiteLLM proxy launch failed: %w
- plan %s branch %s already has an active stream on host %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/89684815dbe02eb1.
Report an issue: GitHub.