{"record":{"id":"ff2b337b1c99a72b","repo":"plandex-ai/plandex","slug":"active-plan-not-found-for-plan-id-s-and-branch-s","errorCode":null,"errorMessage":"active plan not found for plan ID %s and branch %s","messagePattern":"active plan not found for plan ID (.+?) and branch (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/model/plan/build_structured_edits.go","lineNumber":35,"sourceCode":"\tshared \"plandex-shared\"\n)\n\nfunc (fileState *activeBuildStreamFileState) buildStructuredEdits() {\n\tfilePath := fileState.filePath\n\tactiveBuild := fileState.activeBuild\n\tplanId := fileState.plan.Id\n\tbranch := fileState.branch\n\toriginalFile := fileState.preBuildState\n\tparser := fileState.parser\n\n\tif parser == nil {\n\t\tlog.Printf(\"buildStructuredEdits - tree-sitter parser is nil for file %s\\n\", filePath)\n\t}\n\n\tactivePlan := GetActivePlan(planId, branch)\n\tif activePlan == nil {\n\t\tlog.Printf(\"Active plan not found for plan ID %s and branch %s\\n\", planId, branch)\n\t\tfileState.onBuildFileError(fmt.Errorf(\"active plan not found for plan ID %s and branch %s\", planId, branch))\n\t\treturn\n\t}\n\n\tbuildCtx, cancelBuild := context.WithCancel(activePlan.Ctx)\n\n\tproposedContent := activeBuild.FileContent\n\tdesc := activeBuild.FileDescription\n\n\tdescLower := strings.ToLower(desc)\n\tisReplaceOrRemove := strings.Contains(descLower, \"type: replace\") || strings.Contains(descLower, \"type: remove\") || strings.Contains(descLower, \"type: overwrite\")\n\n\tvar autoApplyRes *syntax.ApplyChangesResult\n\tvar autoApplySyntaxErrors []string\n\n\tcalledFastApply := false\n\tvar fastApplyRes string\n\tfastApplyCh := make(chan string, 1)\n","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/build_structured_edits.go#L17-L53","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nfileState.buildFile(ctx, planId, branch, ...)\n// after\nif GetActivePlan(planId, branch) == nil {\n    return fmt.Errorf(\"cannot build: no active plan %s on branch %s; create/activate the plan first\", planId, branch)\n}\nfileState.buildFile(ctx, planId, branch, ...)","handlingStrategy":"validation","validationCode":"if p := GetActivePlan(planId, branch); p == nil {\n    return fmt.Errorf(\"no active plan for %s/%s: create or reactivate the plan before building\", planId, branch)\n}\nif p := GetActivePlan(planId, branch); p != nil && p.Ctx.Err() != nil {\n    return fmt.Errorf(\"plan %s already canceled: %w\", planId, p.Ctx.Err())\n}","typeGuard":"func hasActivePlan(planId string, branch string) bool {\n    p := GetActivePlan(planId, branch)\n    return p != nil && p.Ctx.Err() == nil\n}","tryCatchPattern":"// buildFile-level handling before invoking buildStructuredEdits:\nif !hasActivePlan(planId, branch) {\n    return fmt.Errorf(\"cannot build file %s: no active plan %s on branch %s\", filePath, planId, branch)\n}\nfileState.onBuildFileError = func(err error) {\n    log.Printf(\"build aborted: %v\", err) // surface to caller instead of swallowing\n}","preventionTips":["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"],"tags":["go","plan","lifecycle","state"],"backgroundTag":"active-plan-not-found","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-12T22:17:10.623Z"}