{"record":{"id":"8f0c1bd3343eff7c","repo":"charmbracelet/gum","slug":"error-opening-file-w","errorCode":null,"errorMessage":"error opening file: %w","messagePattern":"error opening file: %w","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"log/command.go","lineNumber":22,"sourceCode":"import (\n\t\"fmt\"\n\t\"math\"\n\t\"os\"\n\t\"strings\"\n\t\"time\"\n\n\t\"charm.land/lipgloss/v2\"\n\tlog \"charm.land/log/v2\"\n)\n\n// Run is the command-line interface for logging text.\nfunc (o Options) Run() error {\n\tl := log.New(os.Stderr)\n\n\tif o.File != \"\" {\n\t\tf, err := os.OpenFile(o.File, os.O_CREATE|os.O_WRONLY|os.O_APPEND, os.ModePerm) //nolint:gosec\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"error opening file: %w\", err)\n\t\t}\n\n\t\tdefer f.Close() //nolint:errcheck\n\t\tl.SetOutput(f)\n\t}\n\n\tl.SetPrefix(o.Prefix)\n\tl.SetLevel(-math.MaxInt32) // log all levels\n\tl.SetReportTimestamp(o.Time != \"\")\n\tif o.MinLevel != \"\" {\n\t\tlvl, err := log.ParseLevel(o.MinLevel)\n\t\tif err != nil {\n\t\t\treturn err //nolint:wrapcheck\n\t\t}\n\t\tl.SetLevel(lvl)\n\t}\n\n\ttimeFormats := map[string]string{","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/charmbracelet/gum/blob/4d089f95507708a71f64dacfe7ca513219dd5267/log/command.go#L4-L40","documentation":"Returned by the log command's Run when os.OpenFile cannot open the requested log file with create/write/append flags. The underlying *PathError is wrapped with %w and names the file and reason. This is a filesystem/permission problem, not a logging problem.","triggerScenarios":"Running the log command with --file pointing to a path that is unwritable, in a nonexistent directory, or otherwise unopenable (e.g. permission denied, read-only filesystem, path is a directory).","commonSituations":"Writing to /var/log or another root-owned dir without sudo; typo'd directory path; running in a read-only container filesystem; SELinux/AppArmor restrictions; disk full (less common).","solutions":["Verify the target directory exists and is writable by the current user (touch <file> to test)","Create the directory first or choose a writable path (e.g. $HOME or $TMPDIR)","Check mount status — read-only filesystems need remounting or a different target","Inspect errors.Unwrap(err) (os.PathError) for the exact syscall reason"],"exampleFix":"// before\ngum log --file /var/log/app.log \"message\"  # permission denied\n// after\ngum log --file \"$HOME/.local/state/app.log\" \"message\"  # writable location","handlingStrategy":"validation","validationCode":"dir := filepath.Dir(logFile)\nif err := os.MkdirAll(dir, 0o755); err != nil { return err }\nif f, err := os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644); err != nil { return err } else { f.Close() }","typeGuard":"func canWriteFile(path string) bool {\n    f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE, 0o644)\n    if err != nil { return false }\n    f.Close(); return true\n}","tryCatchPattern":"err := logCmd.Run()\nvar perr *fs.PathError\nif err != nil && errors.As(err, &perr) {\n    return fmt.Errorf(\"cannot open log file %s: %v\", perr.Path, perr.Err)\n}","preventionTips":["MkdirAll the log directory before invoking","Choose user-writable paths ($HOME, $TMPDIR) over /var/log","Check for read-only mounts and SELinux denials","Pre-flight the path with a touch/open test"],"tags":["go","filesystem","permissions","logging"],"backgroundTag":"file-open-failed","analyzedSha":"4d089f95507708a71f64dacfe7ca513219dd5267","analyzedAt":"2026-08-31T18:45:06.436Z","schemaVersion":2},"datasetVersion":"2026-08-31T19:17:28.585Z"}