{"record":{"id":"ea2df1c42f12cbcc","repo":"plandex-ai/plandex","slug":"error-writing-result-file-v","errorCode":null,"errorMessage":"error writing result file: %v","messagePattern":"error writing result file: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"app/server/db/result_helpers.go","lineNumber":49,"sourceCode":"\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error marshalling result: %v\", err)\n\t}\n\n\tresultsDir := getPlanResultsDir(result.OrgId, result.PlanId)\n\n\terr = os.MkdirAll(resultsDir, 0755)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error creating results dir: %v\", err)\n\t}\n\n\tlog.Printf(\"Storing plan result: %s - %s\", result.Path, result.Id)\n\n\terr = os.WriteFile(filepath.Join(resultsDir, result.Id+\".json\"), bytes, 0644)\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error writing result file: %v\", err)\n\t}\n\n\treturn nil\n\n}\n\ntype CurrentPlanStateParams struct {\n\tOrgId                    string\n\tPlanId                   string\n\tPlanFileResults          []*PlanFileResult\n\tConvoMessageDescriptions []*ConvoMessageDescription\n\tContexts                 []*Context\n}\n\nfunc GetFullCurrentPlanStateParams(orgId, planId string) (CurrentPlanStateParams, error) {\n\terrCh := make(chan error, 3)\n\n\tvar results []*PlanFileResult","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/plandex-ai/plandex/blob/e2d772072efadbe41d2946d97d79be55532dbab5/app/server/db/result_helpers.go#L31-L67","documentation":"StorePlanResult marshals the result and writes it to resultsDir/<id>.json via os.WriteFile. If the write fails (permissions, disk full, I/O error, dir vanished between MkdirAll and WriteFile) it wraps the OS error with this message.","triggerScenarios":"os.WriteFile fails when storing a plan result: read-only filesystem, disk quota/full disk, race where another process deleted the results directory, or the result.Id contains path-hostile characters.","commonSituations":"Disk-full on the server after a large plan; container volume remounted read-only; concurrent cleanup job removing results dir mid-write; running the server under a different user than the one that owns the data dir.","solutions":["Read the wrapped os.PathError to identify path and errno (ENOSPC, EACCES, ENOENT)","Check free disk space and quotas on the data volume","Verify directory permissions for the server process user","Retry once after confirming the results dir exists (guard against racing deletion)","Avoid restarting the plan write pipeline until storage is healthy to prevent partial results"],"exampleFix":"// before\nerr := db.StorePlanResult(result)\n// after\nif err := db.StorePlanResult(result); err != nil {\n\tvar pathErr *os.PathError\n\tif errors.As(err, &pathErr) && errors.Is(pathErr.Err, syscall.ENOSPC) {\n\t\treturn fmt.Errorf(\"out of disk space while storing result %s\", result.Id)\n\t}\n\treturn err\n}","handlingStrategy":"try-catch","validationCode":"func writable(dir string) bool {\n\tf, err := os.CreateTemp(dir, \".w-*\")\n\tif err != nil {\n\t\treturn false\n\t}\n\tf.Close()\n\tos.Remove(f.Name())\n\treturn true\n}\n// call writable(getPlanResultsDir(orgId, planId)) before storing","typeGuard":"func isNoSpace(err error) bool {\n\tvar pe *os.PathError\n\treturn errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOSPC)\n}","tryCatchPattern":"if err := db.StorePlanResult(result); err != nil {\n\tif isNoSpace(err) {\n\t\talertOps(\"disk full\")\n\t}\n\treturn fmt.Errorf(\"StorePlanResult(%s): %w\", result.Id, err)\n}","preventionTips":["Alert on disk usage thresholds well before 100%","Use atomic write (temp file + rename) to avoid partial results","Don't run cleanup jobs concurrently with writes, or make them idempotent","Keep result.Id as a generated UUID (the code already does this) so paths are safe","Remount read-only volumes and restart before resuming writes"],"tags":["go","filesystem","io","disk"],"backgroundTag":"file-write-failed","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"}