plandex-ai/plandex · error

active plan not found for plan %s and branch %s

Error message

active plan not found for plan %s and branch %s

What it means

genPlanDescription needs the active plan (for its context, session ID, and cancellation scope) before generating a plan/commit description via the LLM. When GetActivePlan returns nil for the plan ID + branch, it notifies and returns a 500 ApiError. The description cannot be generated without the live plan session.

Source

Thrown at app/server/model/plan/commit_msg.go:34

	shared "plandex-shared"

	"github.com/sashabaranov/go-openai"
)

func (state *activeTellStreamState) genPlanDescription() (*db.ConvoMessageDescription, *shared.ApiError) {
	auth := state.auth
	plan := state.plan
	planId := plan.Id
	branch := state.branch
	settings := state.settings
	clients := state.clients
	authVars := state.authVars
	orgUserConfig := state.orgUserConfig
	config := settings.GetModelPack().CommitMsg

	activePlan := GetActivePlan(planId, branch)
	if activePlan == nil {
		go notify.NotifyErr(notify.SeverityError, fmt.Errorf("active plan not found for plan %s and branch %s", planId, branch))

		return nil, &shared.ApiError{
			Type:   shared.ApiErrorTypeOther,
			Status: http.StatusInternalServerError,
			Msg:    fmt.Sprintf("active plan not found for plan %s and branch %s", planId, branch),
		}
	}

	baseModelConfig := config.GetBaseModelConfig(authVars, settings, orgUserConfig)

	var sysPrompt string
	var tools []openai.Tool
	var toolChoice *openai.ToolChoice

	if baseModelConfig.PreferredOutputFormat == shared.ModelOutputFormatXml {
		sysPrompt = prompts.SysDescribeXml
	} else {
		sysPrompt = prompts.SysDescribe

View on GitHub (pinned to e2d772072e)

Solutions

  1. Verify the planId and branch match the currently streaming plan (GET the plan's status first)
  2. Retry the tell request so the plan is re-activated before description generation
  3. Check server logs for an earlier Stop or DeleteActivePlan call for this plan
  4. Report/persist a description fallback so a finished plan doesn't lose its commit message

Example fix

// before
desc, apiErr := state.genPlanDescription()
// after: check the plan is still active first
if modelPlan.GetActivePlan(planId, branch) == nil {
    log.Println("plan no longer active; skipping description")
    return
}
desc, apiErr := state.genPlanDescription()
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure plan is streaming before asking for a description
resp, _ := http.Get(baseURL + "/plans/" + planId + "/" + branch + "/status")
// only proceed if status indicates an active/streaming plan

Try / catch

desc, apiErr := state.genPlanDescription()
if apiErr != nil && strings.Contains(apiErr.Msg, "active plan not found") {
    log.Printf("plan %s/%s deactivated before description; skipping", planId, branch)
    return
}

Prevention

When it happens

Trigger: The tell stream that should have registered the active plan has ended (finished, errored, stopped, or deleted via DeleteActivePlan) before genPlanDescription runs; or the planId/branch pair passed to the stream does not match any registered active plan.

Common situations: Plan finished extremely fast and was deactivated before the description step; concurrent Stop request during streaming; using a stale planId after a server restart; branch name typo in the API call.

Related errors


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