{"record":{"id":"14cc7694eb108bdb","repo":"wavetermdev/waveterm","slug":"error-writing-to-file-s-w","errorCode":null,"errorMessage":"error writing to file %s: %w","messagePattern":"error writing to file (.+?): %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"cmd/wsh/cmd/wshcmd-termscrollback.go","lineNumber":96,"sourceCode":"\tresult, err := wshclient.TermGetScrollbackLinesCommand(RpcClient, scrollbackData, &wshrpc.RpcOpts{\n\t\tRoute:   wshutil.MakeFeBlockRouteId(fullORef.OID),\n\t\tTimeout: 5000,\n\t})\n\tif err != nil {\n\t\treturn fmt.Errorf(\"error getting terminal scrollback: %w\", err)\n\t}\n\n\t// Format the output\n\toutput := strings.Join(result.Lines, \"\\n\")\n\tif len(result.Lines) > 0 {\n\t\toutput += \"\\n\" // Add final newline\n\t}\n\n\t// Write to file or stdout\n\tif termScrollbackOutputFile != \"\" {\n\t\terr = os.WriteFile(termScrollbackOutputFile, []byte(output), 0644)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error writing to file %s: %w\", termScrollbackOutputFile, err)\n\t\t}\n\t\tfmt.Printf(\"terminal scrollback written to %s (%d lines)\\n\", termScrollbackOutputFile, len(result.Lines))\n\t} else {\n\t\tfmt.Print(output)\n\t}\n\n\treturn nil\n}\n","sourceCodeStart":78,"sourceCodeEnd":105,"githubUrl":"https://github.com/wavetermdev/waveterm/blob/a4447c1563b2df285ab89e76c82f91e1a1a49c1e/cmd/wsh/cmd/wshcmd-termscrollback.go#L78-L105","documentation":"When the --output-file flag is set, wsh writes the scrollback text with os.WriteFile using 0644 permissions. Any filesystem failure (bad path, missing directory, permission denied, disk full) is wrapped with this message naming the file.","triggerScenarios":"os.WriteFile failing for termScrollbackOutputFile: parent directory doesn't exist, no write permission, read-only filesystem, or path is a directory.","commonSituations":"Typo in the output path; writing into a directory created by root; output on a full or read-only disk; using `~` unexpanded because the CLI doesn't expand it.","solutions":["Check the path exists and is writable: verify the parent directory exists (`mkdir -p`) and fix the filename.","Avoid `~` — pass an absolute path since os.WriteFile does not expand tilde.","Check filesystem permissions and free space (`ls -ld`, `df -h`)."],"exampleFix":"// before\nerr = os.WriteFile(termScrollbackOutputFile, []byte(output), 0644)\n// after\nexpandedPath, err := wavebase.ExpandHomeDir(termScrollbackOutputFile)\nif err != nil {\n\treturn fmt.Errorf(\"invalid output path %s: %w\", termScrollbackOutputFile, err)\n}\nif err := os.MkdirAll(filepath.Dir(expandedPath), 0755); err != nil {\n\treturn fmt.Errorf(\"creating output dir: %w\", err)\n}\nerr = os.WriteFile(expandedPath, []byte(output), 0644)","handlingStrategy":"validation","validationCode":"// validate the output path before writing\nif termScrollbackOutputFile != \"\" {\n\tpath, _ := filepath.Abs(os.ExpandEnv(termScrollbackOutputFile))\n\tif st, err := os.Stat(filepath.Dir(path)); err != nil || !st.IsDir() {\n\t\tfmt.Fprintf(os.Stderr, \"output directory does not exist: %s\\n\", filepath.Dir(path))\n\t\tos.Exit(1)\n\t}\n}","typeGuard":null,"tryCatchPattern":"err = os.WriteFile(termScrollbackOutputFile, []byte(output), 0644)\nif err != nil {\n\tif errors.Is(err, fs.ErrPermission) {\n\t\t// permission denied: fix ownership/mode or pick another path\n\t} else if errors.Is(err, fs.ErrNotExist) {\n\t\t// create parent dirs first\n\t}\n\treturn fmt.Errorf(\"error writing to file %s: %w\", termScrollbackOutputFile, err)\n}","preventionTips":["Use absolute paths; expand `~` and env vars yourself before passing them.","Pre-create the output directory (`mkdir -p`).","Check disk space and permissions when writing to shared/system locations."],"tags":["filesystem","io","cli"],"backgroundTag":"file-write-permission-denied","analyzedSha":"a4447c1563b2df285ab89e76c82f91e1a1a49c1e","analyzedAt":"2026-09-01T15:26:23.972Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}