{"record":{"id":"5ee561461c2eca5b","repo":"plandex-ai/plandex","slug":"error-starting-whole-file-build-v","errorCode":null,"errorMessage":"error starting whole file build: %v","messagePattern":"error starting whole file build: (.+?)","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"app/server/model/plan/build_race.go","lineNumber":86,"sourceCode":"\t}\n\n\tsendErr := func(err error) {\n\t\tselect {\n\t\tcase errCh <- err:\n\t\tcase <-buildCtx.Done():\n\t\t\tlog.Printf(\"buildRace - context canceled, skipping sendErr\")\n\t\t}\n\t}\n\n\tstartedFallbacks := false\n\n\tstartWholeFileBuild := func(comments string) {\n\t\tlog.Printf(\"buildRace - starting whole file fallback build\")\n\t\tgo func() {\n\t\t\tdefer func() {\n\t\t\t\tif r := recover(); r != nil {\n\t\t\t\t\tlog.Printf(\"panic in startWholeFileBuild: %v\\n%s\", r, debug.Stack())\n\t\t\t\t\tsendErr(fmt.Errorf(\"error starting whole file build: %v\", r))\n\t\t\t\t\truntime.Goexit() // don't allow outer function to continue and double-send to channel\n\t\t\t\t}\n\t\t\t}()\n\t\t\tselect {\n\t\t\tcase <-buildCtx.Done():\n\t\t\t\tlog.Printf(\"buildRace - context already canceled, skipping whole file build\")\n\t\t\t\treturn\n\t\t\tdefault:\n\t\t\t}\n\n\t\t\tcontent, err := fileState.buildWholeFileFallback(buildCtx, proposedContent, desc, comments, sessionId)\n\n\t\t\tif err != nil {\n\t\t\t\tif errors.Is(err, context.Canceled) {\n\t\t\t\t\tlog.Printf(\"Context canceled during whole file build\")\n\t\t\t\t\treturn\n\t\t\t\t}\n","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/model/plan/build_race.go#L68-L104","documentation":"In buildRace, startWholeFileBuild launches a goroutine that runs the whole-file fallback build; its recover() defer catches any panic in that goroutine, logs the stack, converts the panic value to \"error starting whole file build: %v\" and forwards it via sendErr to errCh before runtime.Goexit() stops the goroutine. This error means the fallback whole-file build path crashed unexpectedly (not that the model output was invalid).","triggerScenarios":"A panic occurs in the goroutine started by startWholeFileBuild — before or inside fileState.buildWholeFileFallback(buildCtx, proposedContent, desc, comments, sessionId) — e.g. nil fileState fields (preBuildState), bad proposedContent assumptions, or a nil map write in fallback setup.","commonSituations":"proposedContent or file state is nil/malformed when the race detects syntax errors and starts the fallback; session/context state torn down while the fallback goroutine starts; a regression in buildWholeFileFallback or syntax parsing utilities.","solutions":["Inspect the panic stack trace logged as \"panic in startWholeFileBuild\" for the exact crash site","Validate fileState.preBuildState and proposedContent are non-nil before calling startWholeFileBuild","Check buildCtx is still live (the goroutine already skips when canceled) and sessionId state is valid","Add guards/fixes in buildWholeFileFallback, then re-run the build; sendErr safely feeds the race's errCh"],"exampleFix":"// before\nstartWholeFileBuild(comments) // panics when proposedContent is nil\n// after\nif proposedContent == \"\" || fileState.preBuildState == nil {\n\tsendErr(fmt.Errorf(\"cannot start whole file build: missing file state or proposed content\"))\n\treturn\n}\nstartWholeFileBuild(comments)","handlingStrategy":"validation","validationCode":"if fileState == nil || fileState.preBuildState == nil || proposedContent == \"\" {\n\treturn fmt.Errorf(\"cannot run whole file fallback: missing file state or proposed content\")\n}\nif err := buildCtx.Err(); err != nil {\n\treturn fmt.Errorf(\"build context already canceled: %w\", err)\n}","typeGuard":"func canRunWholeFileFallback(fs *activeBuildStreamFileState, proposed string) bool {\n\treturn fs != nil && fs.preBuildState != nil && proposed != \"\"\n}","tryCatchPattern":"res, err := buildRace(buildCtx, cancelBuild, params)\nif err != nil {\n\tif strings.Contains(err.Error(), \"error starting whole file build\") {\n\t\t// panic in fallback goroutine: inspect stack trace, don't blindly retry\n\t\tlog.Printf(\"whole-file fallback crashed: %v\", err)\n\t}\n\treturn res, err\n}","preventionTips":["Validate preBuildState and proposedContent before starting the fallback race","Ensure buildWholeFileFallback is nil-safe across all session/context inputs","Keep syntax-parsing utilities covered by unit tests to avoid fallback-path panics","Treat this panic error as a bug to fix, not a transient condition to retry"],"tags":["go","panic","concurrency","fallback"],"backgroundTag":"goroutine-panic-recovered","analyzedSha":"e2d772072efadbe41d2946d97d79be55532dbab5","analyzedAt":"2026-09-05T20:56:53.631Z","contentChangedAt":"2026-09-05T20:56:53.631Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}