{"record":{"id":"b66885cabf03ab03","repo":"plandex-ai/plandex","slug":"error-getting-plan-file-results-v","errorCode":null,"errorMessage":"error getting plan file results: %v","messagePattern":"error getting plan file results: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/result_helpers.go","lineNumber":82,"sourceCode":"func GetFullCurrentPlanStateParams(orgId, planId string) (CurrentPlanStateParams, error) {\n\terrCh := make(chan error, 3)\n\n\tvar results []*PlanFileResult\n\tvar convoMessageDescriptions []*ConvoMessageDescription\n\tvar contexts []*Context\n\n\tgo func() {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tlog.Printf(\"panic in GetFullCurrentPlanStateParams: %v\\n%s\", r, debug.Stack())\n\t\t\t\terrCh <- fmt.Errorf(\"panic in GetFullCurrentPlanStateParams: %v\\n%s\", r, debug.Stack())\n\t\t\t\truntime.Goexit() // don't allow outer function to continue and double-send to channel\n\t\t\t}\n\t\t}()\n\n\t\tres, err := GetPlanFileResults(orgId, planId)\n\t\tif err != nil {\n\t\t\terrCh <- fmt.Errorf(\"error getting plan file results: %v\", err)\n\t\t\treturn\n\t\t}\n\t\tresults = res\n\t\terrCh <- nil\n\t}()\n\n\tgo func() {\n\t\tdefer func() {\n\t\t\tif r := recover(); r != nil {\n\t\t\t\tlog.Printf(\"panic in GetFullCurrentPlanStateParams: %v\\n%s\", r, debug.Stack())\n\t\t\t\terrCh <- fmt.Errorf(\"panic in GetFullCurrentPlanStateParams: %v\\n%s\", r, debug.Stack())\n\t\t\t\truntime.Goexit() // don't allow outer function to continue and double-send to channel\n\t\t\t}\n\t\t}()\n\t\tres, err := GetConvoMessageDescriptions(orgId, planId)\n\t\tif err != nil {\n\t\t\terrCh <- fmt.Errorf(\"error getting latest plan build description: %v\", err)\n\t\t\treturn","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/result_helpers.go#L64-L100","documentation":"Inside the first worker goroutine of GetFullCurrentPlanStateParams, GetPlanFileResults reads every JSON file in the plan's results directory. Any error other than a missing directory (which is treated as empty) is wrapped with this message and sent to the caller.","triggerScenarios":"GetPlanFileResults fails while GetFullCurrentPlanStateParams runs: unreadable results directory (EACCES), a result file deleted between ReadDir and ReadFile, unreadable/corrupt JSON file, or a panic in one of its per-file goroutines.","commonSituations":"Permissions changed on the plans data dir; a result file partially written by a crashed process; another server instance cleaning up files concurrently; disk I/O errors.","solutions":["Inspect the wrapped error for the specific failing path","Fix permissions on the plan's results directory","Remove or repair corrupt/partial result JSON files","Ensure only one server instance manages the plans data dir to avoid delete races","Treat 'error reading result files' children as data-corruption signals and re-sync storage from backup"],"exampleFix":"// before\nif err != nil {\n\treturn CurrentPlanStateParams{}, err\n}\n// after\nif err != nil {\n\tlog.Printf(\"plan file results unavailable for %s/%s: %v — continuing with empty state\", orgId, planId, err)\n\treturn CurrentPlanStateParams{OrgId: orgId, PlanId: planId}, nil\n}","handlingStrategy":"fallback","validationCode":"dir := getPlanResultsDir(orgId, planId)\nif st, err := os.Stat(dir); err == nil && !st.IsDir() {\n\treturn fmt.Errorf(\"results path is a file, not a directory: %s\", dir)\n}","typeGuard":"func nilSafeResults(rs []*db.PlanFileResult) []*db.PlanFileResult {\n\tif rs == nil {\n\t\treturn []*db.PlanFileResult{}\n\t}\n\treturn rs\n}","tryCatchPattern":"params, err := db.GetFullCurrentPlanStateParams(orgId, planId)\nif err != nil && strings.Contains(err.Error(), \"error getting plan file results\") {\n\t// degrade to empty plan state instead of failing the request\n\tparams = db.CurrentPlanStateParams{OrgId: orgId, PlanId: planId}\n}","preventionTips":["Single-writer discipline: one server instance owns the plans data dir","Treat os.IsNotExist as empty (the code already does) — fix other errnos at the infra level","Back up plan data dirs and verify restorability","Detect and quarantine corrupt JSON files with a periodic scan job","Watch logs for partial-write symptoms (truncated JSON) after crashes"],"tags":["go","filesystem","json","io"],"backgroundTag":"file-read-failed","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"}