plandex-ai/plandex · error

active plan not found

Error message

active plan not found

What it means

loadBuildFile looks up the in-memory active plan for (planId, branch) via GetActivePlan and fails with this error when no active plan is registered. The active plan map only contains plans whose build/stream is currently tracked in this process, so a miss means the plan was never registered, was already completed/cleaned up, or the process restarted.

Source

Thrown at app/server/model/plan/build_load.go:168

	})

	state.modelContext = modelContext
	state.settings = settings
	state.orgUserConfig = orgUserConfig

	return pendingBuildsByPath, nil
}

func (state *activeBuildStreamFileState) loadBuildFile(activeBuild *types.ActiveBuild) error {
	currentOrgId := state.currentOrgId
	planId := state.plan.Id
	branch := state.branch
	filePath := state.filePath

	activePlan := GetActivePlan(planId, branch)

	if activePlan == nil {
		return fmt.Errorf("active plan not found")
	}

	convoMessageId := activeBuild.ReplyId

	parser, lang, fallbackParser, fallbackLang := syntax.GetParserForPath(filePath)

	if parser != nil {
		validationRes, err := syntax.ValidateWithParsers(activePlan.Ctx, lang, parser, fallbackLang, fallbackParser, state.preBuildState)
		if err != nil {
			log.Printf(" error validating original file syntax: %v\n", err)
			return fmt.Errorf("error validating original file syntax: %v", err)
		}

		state.language = validationRes.Lang
		state.parser = validationRes.Parser

		state.builderRun.Lang = string(validationRes.Lang)

View on GitHub (pinned to e2d772072e)

Solutions

  1. Confirm the plan build for this planId+branch was actually started in the current process (call the plan-build start/init path before execPlanBuild).
  2. Check for server restarts or multiple replicas — route the build to the instance that holds the active plan, or persist active plans.
  3. Verify the branch name matches the branch used when the active plan was created.
  4. Log the contents of the active plan registry for the planId to see when/why the entry disappeared.
  5. Add/keep-alive registration: re-create the active plan via UpdateActivePlan before loading build files.

Example fix

// before
activePlan := GetActivePlan(planId, branch)
if activePlan == nil {
    return fmt.Errorf("active plan not found")
}
// after
activePlan := GetActivePlan(planId, branch)
if activePlan == nil {
    return fmt.Errorf("active plan not found for plan %s branch %s (was it completed or lost on restart?)", planId, branch)
}
Defensive patterns

Strategy: validation

Validate before calling

if GetActivePlan(planId, branch) == nil {
    return fmt.Errorf("no active plan for %s/%s — start the plan build first", planId, branch)
}

Type guard

func hasActivePlan(planId, branch string) bool {
    return GetActivePlan(planId, branch) != nil
}

Prevention

When it happens

Trigger: loadBuildFile is called (via execPlanBuild) with a planId/branch pair that has no entry in the active plan registry: the plan finished and was removed, the server restarted mid-build, the branch name is wrong or changed, or the active plan was evicted due to an earlier error.

Common situations: Resuming a build after an app deploy/restart (in-memory state lost); a second build stream racing with a completed one on the same branch; a client passing a stale plan ID or branch; plans cleaned up by a timeout/manager goroutine.

Related errors


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