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

  1. Log/verify the exact planId and branch being looked up vs what was registered
  2. Ensure the active plan is created (AddActivePlan/UpdateActivePlan) before loadTellPlan runs
  3. Check the branch value matches the one used when the stream started
  4. 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

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


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