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)
returnView on GitHub (pinned to e2d772072e)
Solutions
- Check plan status first (or handle 404) before issuing proxied calls; refresh the plan list in the UI.
- Verify the planId/branch pair is current — list active plans from the DB or API.
- If the plan should be running, restart it and confirm its model stream row is registered (GetActiveModelStream should return a row).
- Make clients treat 404 here as 'plan finished' and stop polling/reconnect to a new plan.
- 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
- Poll plan status before and during proxied interactions; stop on finished/errored.
- Clear or refetch plan lists after reconnects/redeploys — never reuse stale planIds.
- Confirm the plan's instance registered its model stream at startup.
- Treat 404 as a lifecycle signal (plan ended), not a retryable error.
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.