{"record":{"id":"27904df3d5423097","repo":"gastownhall/beads","slug":"failed-to-create-output-file-w","errorCode":null,"errorMessage":"failed to create output file: %w","messagePattern":"failed to create output file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/bd/doctor.go","lineNumber":1111,"sourceCode":"\t\tDetail:   dc.Detail,\n\t\tFix:      dc.Fix,\n\t\tCategory: dc.Category,\n\t}\n}\n\n// convertWithCategory converts a doctor check and sets its category\nfunc convertWithCategory(dc doctor.DoctorCheck, category string) doctorCheck {\n\tcheck := convertDoctorCheck(dc)\n\tcheck.Category = category\n\treturn check\n}\n\n// exportDiagnostics writes the doctor result to a JSON file\nfunc exportDiagnostics(result doctorResult, outputPath string) error {\n\t// #nosec G304 - outputPath is a user-provided flag value for file generation\n\tf, err := os.Create(outputPath)\n\tif err != nil {\n\t\treturn fmt.Errorf(\"failed to create output file: %w\", err)\n\t}\n\tdefer f.Close()\n\n\tencoder := json.NewEncoder(f)\n\tencoder.SetIndent(\"\", \"  \")\n\tif err := encoder.Encode(result); err != nil {\n\t\treturn fmt.Errorf(\"failed to write JSON: %w\", err)\n\t}\n\n\treturn nil\n}\n\nfunc printDiagnostics(result doctorResult) {\n\t// Pre-calculate counts and collect issues grouped by category\n\tchecksByCategory := make(map[string][]doctorCheck)\n\tissuesByCategory := make(map[string][]doctorCheck)\n\tvar passCount, warnCount, failCount int\n\thasIssues := false","sourceCodeStart":1093,"sourceCodeEnd":1129,"githubUrl":"https://github.com/gastownhall/beads/blob/71377f276968b452ee607177637970a4ff888584/cmd/bd/doctor.go#L1093-L1129","documentation":"exportDiagnostics wraps any error returned by os.Create when it cannot open the requested output file for writing. The doctor command uses this to report that the JSON diagnostics file could not be created. The wrapped error (%w) carries the OS-level reason (permissions, path issues, etc.).","triggerScenarios":"Calling `bd doctor` with an --output path whose parent directory does not exist, is not writable, or where the path is a directory; os.Create then fails and exportDiagnostics wraps it at cmd/bd/doctor.go:1111.","commonSituations":"Typo'd output path (e.g. -o /nonexistent/dir/out.json), read-only filesystem, no write permission in the target directory, path pointing to an existing directory, or running without sufficient privileges in restricted locations.","solutions":["Create the parent directory first (mkdir -p <dir>) or correct the output path","Check directory write permissions (ls -ld <dir>) and fix with chmod/chown or pick another directory","Ensure the path is a file, not an existing directory","Run from a location/filesystem that is writable (avoid read-only mounts, full disks via df -h)"],"exampleFix":"// before\nbd doctor --output /nonexistent/dir/diag.json\n// after\nmkdir -p ./diagnostics\nbd doctor --output ./diagnostics/diag.json","handlingStrategy":"validation","validationCode":"import \"os\"\nfunc ensureWritable(path string) error {\n\tdir := filepath.Dir(path)\n\tif st, err := os.Stat(dir); err != nil {\n\t\treturn fmt.Errorf(\"output dir missing: %w\", err)\n\t} else if !st.IsDir() {\n\t\treturn fmt.Errorf(\"%s is not a directory\", dir)\n\t}\n\tf, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY, 0o644)\n\tif err != nil { return err }\n\treturn f.Close()\n}","typeGuard":null,"tryCatchPattern":"if err := exportDiagnostics(result, outPath); err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) {\n\t\tlog.Fatalf(\"cannot write %s: %v (check dir exists and is writable)\", pe.Path, pe.Err)\n\t}\n\treturn err\n}","preventionTips":["Always create the parent directory (os.MkdirAll) before passing an output path","Write exports to a known-writable location (cwd or temp dir)","Verify the output path is not an existing directory","Check free disk space in scripts before exporting"],"tags":["filesystem","io","doctor","export"],"backgroundTag":"file-write-permission-denied","analyzedSha":"71377f276968b452ee607177637970a4ff888584","analyzedAt":"2026-08-30T18:55:39.744Z","schemaVersion":2},"datasetVersion":"2026-08-30T23:17:21.991Z"}