plandex-ai/plandex · error
active plan not found for plan ID %s and branch %s
Error message
active plan not found for plan ID %s and branch %s
What it means
buildStructuredEdits requires an active plan for the given planId and branch. GetActivePlan returns nil when no plan is registered (plan never created, already stopped/cleaned up, or wrong branch), so the function reports this error via fileState.onBuildFileError and aborts the build instead of dereferencing a nil plan.
Source
Thrown at app/server/model/plan/build_structured_edits.go:35
shared "plandex-shared"
)
func (fileState *activeBuildStreamFileState) buildStructuredEdits() {
filePath := fileState.filePath
activeBuild := fileState.activeBuild
planId := fileState.plan.Id
branch := fileState.branch
originalFile := fileState.preBuildState
parser := fileState.parser
if parser == nil {
log.Printf("buildStructuredEdits - tree-sitter parser is nil for file %s\n", filePath)
}
activePlan := GetActivePlan(planId, branch)
if activePlan == nil {
log.Printf("Active plan not found for plan ID %s and branch %s\n", planId, branch)
fileState.onBuildFileError(fmt.Errorf("active plan not found for plan ID %s and branch %s", planId, branch))
return
}
buildCtx, cancelBuild := context.WithCancel(activePlan.Ctx)
proposedContent := activeBuild.FileContent
desc := activeBuild.FileDescription
descLower := strings.ToLower(desc)
isReplaceOrRemove := strings.Contains(descLower, "type: replace") || strings.Contains(descLower, "type: remove") || strings.Contains(descLower, "type: overwrite")
var autoApplyRes *syntax.ApplyChangesResult
var autoApplySyntaxErrors []string
calledFastApply := false
var fastApplyRes string
fastApplyCh := make(chan string, 1)
View on GitHub (pinned to e2d772072e)
Solutions
- Verify the planId and branch passed to buildFile match an existing active plan (list active plans before building)
- Ensure the plan isn't canceled/stopped before the build runs; check plan lifecycle ordering (create/activate before build)
- If the plan context can be canceled mid-build, re-create or re-activate the plan and retry the file build
- Fix stale client state that is resubmitting old plan IDs after a restart
Example fix
// before
fileState.buildFile(ctx, planId, branch, ...)
// after
if GetActivePlan(planId, branch) == nil {
return fmt.Errorf("cannot build: no active plan %s on branch %s; create/activate the plan first", planId, branch)
}
fileState.buildFile(ctx, planId, branch, ...) Defensive patterns
Strategy: validation
Validate before calling
if p := GetActivePlan(planId, branch); p == nil {
return fmt.Errorf("no active plan for %s/%s: create or reactivate the plan before building", planId, branch)
}
if p := GetActivePlan(planId, branch); p != nil && p.Ctx.Err() != nil {
return fmt.Errorf("plan %s already canceled: %w", planId, p.Ctx.Err())
} Type guard
func hasActivePlan(planId string, branch string) bool {
p := GetActivePlan(planId, branch)
return p != nil && p.Ctx.Err() == nil
} Try / catch
// buildFile-level handling before invoking buildStructuredEdits:
if !hasActivePlan(planId, branch) {
return fmt.Errorf("cannot build file %s: no active plan %s on branch %s", filePath, planId, branch)
}
fileState.onBuildFileError = func(err error) {
log.Printf("build aborted: %v", err) // surface to caller instead of swallowing
} Prevention
- Always check GetActivePlan(planId, branch) before issuing a build for a plan
- Track plan lifecycle (create → active → stopped) and reject builds for non-active plans early
- Guard against cancel/build races: don't cancel a plan while a buildFile call is in flight, or re-check on cancellation
- Persist/revalidate planId+branch on the client so stale IDs from a previous session aren't resubmitted
When it happens
Trigger: Calling buildStructuredEdits (via buildFile) with a planId/branch that has no active plan — the plan was never started, was stopped/canceled (its context canceled and it was removed), or a branch mismatch means GetActivePlan(planId, branch) finds nothing.
Common situations: Build request arriving after plan cancellation or session teardown (race between cancel and in-flight build), stale planId reused after restart, or a branch name that differs from the branch the plan was created under.
Related errors
- no current plan
- no current plan
- no current project
- active plan not found
- active plan not found for plan ID %s and branch %s
AI-assisted analysis of plandex-ai/plandex@e2d772072e (2026-09-05).
Data as JSON: /api/errors/ff2b337b1c99a72b.
Report an issue: GitHub.