plandex-ai/plandex · error
no active plan with id %s
Error message
no active plan with id %s
What it means
setActivePlan in tell_load.go looks up the in-memory active plan via GetActivePlan(plan.Id, branch) and returns 'no active plan with id %s' when the lookup returns nil. An active plan only exists in memory while a tell stream is running; if it has been evicted, never registered, or belongs to a different branch, this error fires. Called from loadTellPlan and handleStreamFinished.
Source
Thrown at app/server/model/plan/tell_load.go:436
UpdateActivePlan(planId, branch, func(ap *types.ActivePlan) {
for _, path := range toUnskipPaths {
delete(ap.SkippedPaths, path)
}
})
}
}
return nil
}
func (state *activeTellStreamState) setActivePlan() error {
plan := state.plan
branch := state.branch
active := GetActivePlan(plan.Id, branch)
if active == nil {
return fmt.Errorf("no active plan with id %s", plan.Id)
}
state.activePlan = active
return nil
}
View on GitHub (pinned to e2d772072e)
Solutions
- Log/verify the exact planId and branch being looked up vs what was registered
- Ensure the active plan is created (AddActivePlan/UpdateActivePlan) before loadTellPlan runs
- Check the branch value matches the one used when the stream started
- Treat a missing active plan as a client-side stale request: abort rather than retry
Example fix
// before
active := GetActivePlan(plan.Id, branch)
if active == nil {
return fmt.Errorf("no active plan with id %s", plan.Id)
}
// after
active := GetActivePlan(plan.Id, branch)
if active == nil {
log.Printf("active plan missing: id=%s branch=%q (registered branches checked)", plan.Id, branch)
return fmt.Errorf("no active plan with id %s on branch %s", plan.Id, branch)
} Defensive patterns
Strategy: type-guard
Validate before calling
active := GetActivePlan(planId, branch)
if active == nil {
return fmt.Errorf("no active plan with id %s on branch %s", planId, branch)
} Type guard
func isActivePlanAvailable(planId, branch string) bool {
return GetActivePlan(planId, branch) != nil
} Try / catch
active := GetActivePlan(plan.Id, branch)
if active == nil {
return fmt.Errorf("no active plan with id %s", plan.Id)
}
_ = active // safe to use below Prevention
- Never reuse a branch string from client input; derive it from the active stream
- Check active plan existence before any resume/continue call
- Clean up active plans deterministically in one code path only
- After a server restart, treat old stream requests as stale and re-initiate
When it happens
Trigger: GetActivePlan(planId, branch) returns nil: the stream already finished and was removed from the registry, the branch string doesn't match the one the active plan was registered under (e.g. 'main' vs actual branch), server restarted losing in-memory state, or loadTellPlan invoked for a plan that has no running stream.
Common situations: Branch-name mismatch after a checkout/rename; client resuming a tell request after server restart; duplicate stream-finish handling after the active plan was cleared.
Related errors
- active plan not found for plan ID %s on branch %s
- error reading JSON file: %v
- error reading convo file: %v
- error reading apply file: %v
- active plan not found
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/a0eb0cc850dc02c8.
Report an issue: GitHub.