{"record":{"id":"1d29b6f29157639c","repo":"shadow1ng/fscan","slug":"failed-to-create-txt-file-w","errorCode":null,"errorMessage":"failed to create TXT file: %w","messagePattern":"failed to create TXT file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/output/writers.go","lineNumber":93,"sourceCode":"// TXTWriter - 文本格式写入器\n// =============================================================================\n\n// TXTWriter 文本格式写入器（分类缓冲，按类型聚合输出）\ntype TXTWriter struct {\n\tfile         *os.File\n\tbufWriter    *bufio.Writer\n\tmu           sync.Mutex\n\tclosed       bool\n\tbuffer       *ResultBuffer // 内存分类缓冲\n\trealtimeFile *os.File      // 实时备份文件\n\trealtimePath string        // 实时备份文件路径\n}\n\n// NewTXTWriter 创建文本写入器\nfunc NewTXTWriter(filePath string) (*TXTWriter, error) {\n\tfile, err := os.OpenFile(filePath, DefaultFileFlags, DefaultFilePermissions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create TXT file: %w\", err)\n\t}\n\n\t// 创建实时备份文件（防崩溃丢数据）\n\trealtimePath := filePath + \".realtime.tmp\"\n\trealtimeFile, err := os.OpenFile(realtimePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, DefaultFilePermissions)\n\tif err != nil {\n\t\tfile.Close()\n\t\treturn nil, fmt.Errorf(\"failed to create realtime backup file: %w\", err)\n\t}\n\n\treturn &TXTWriter{\n\t\tfile:         file,\n\t\tbufWriter:    bufio.NewWriter(file),\n\t\tbuffer:       NewResultBuffer(),\n\t\trealtimeFile: realtimeFile,\n\t\trealtimePath: realtimePath,\n\t}, nil\n}","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/output/writers.go#L75-L111","documentation":"Wrap of an os.OpenFile failure in NewTXTWriter: the TXT output file at filePath could not be created/opened with the configured flags and permissions (common causes: a directory in the path does not exist, permission denied, or the path is invalid). The %w preserves the underlying OS error for errors.Is/As inspection.","triggerScenarios":"Output directory does not exist, permission denied on the path, path is a directory, disk full, or invalid characters in filePath on the target OS.","commonSituations":"Read-only output directory, missing parent directory (createOutputDir not run or wrong path), running under a service account without write access, SELinux/container volume restrictions.","solutions":["Check the wrapped error: if 'no such file or directory', create the parent directory first","Fix permissions (chmod/chown or run with a user that can write the output path)","Verify the path is a file location, not an existing directory, and that the path is valid on the OS"],"exampleFix":"// before\nw, err := NewTXTWriter(\"/nonexistent/dir/out.txt\")\n// after\nos.MkdirAll(\"/nonexistent/dir\", 0o755)\nw, err := NewTXTWriter(\"/nonexistent/dir/out.txt\")","handlingStrategy":"validation","validationCode":"if info, err := os.Stat(filepath.Dir(filePath)); err != nil || !info.IsDir() {\n    os.MkdirAll(filepath.Dir(filePath), 0o755)\n}\nif info, err := os.Stat(filePath); err == nil && info.IsDir() {\n    return errors.New(\"output path is a directory\")\n}","typeGuard":null,"tryCatchPattern":"w, err := NewTXTWriter(path)\nif err != nil {\n    var pe *fs.PathError\n    if errors.As(err, &pe) && errors.Is(pe.Err, fs.ErrPermission) {\n        return fmt.Errorf(\"cannot write output %s: permission denied\", path)\n    }\n    return err\n}","preventionTips":["Create the output directory before constructing writers","Run the scanner with a user that has write access to the output path","Validate the output path is not an existing directory","Check free disk space before large scans"],"tags":["output","file","permissions"],"backgroundTag":"file-open-failed","analyzedSha":"95cc12e753bf43de7004e5aef42a9ffba3934303","analyzedAt":"2026-09-06T17:07:30.094Z","contentChangedAt":"2026-09-06T17:07:30.094Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}