{"record":{"id":"a3b470b5e9fe2a4d","repo":"shadow1ng/fscan","slug":"failed-to-create-json-file-w","errorCode":null,"errorMessage":"failed to create JSON file: %w","messagePattern":"failed to create JSON file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"common/output/writers.go","lineNumber":482,"sourceCode":"\tHosts    []*ScanResult `json:\"hosts,omitempty\"`\n\tPorts    []*ScanResult `json:\"ports,omitempty\"`\n\tServices []*ScanResult `json:\"services,omitempty\"`\n\tVulns    []*ScanResult `json:\"vulns,omitempty\"`\n}\n\n// JSONSummary 扫描摘要\ntype JSONSummary struct {\n\tTotalHosts    int `json:\"total_hosts\"`\n\tTotalPorts    int `json:\"total_ports\"`\n\tTotalServices int `json:\"total_services\"`\n\tTotalVulns    int `json:\"total_vulns\"`\n}\n\n// NewJSONWriter 创建JSON写入器\nfunc NewJSONWriter(filePath string) (*JSONWriter, error) {\n\tfile, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, DefaultFilePermissions)\n\tif err != nil {\n\t\treturn nil, fmt.Errorf(\"failed to create JSON file: %w\", err)\n\t}\n\n\t// 创建实时备份文件（NDJSON格式，每行一个JSON对象）\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 &JSONWriter{\n\t\tfile:         file,\n\t\tbuffer:       NewResultBuffer(),\n\t\trealtimeFile: realtimeFile,\n\t\trealtimePath: realtimePath,\n\t}, nil\n}\n","sourceCodeStart":464,"sourceCodeEnd":500,"githubUrl":"https://github.com/shadow1ng/fscan/blob/95cc12e753bf43de7004e5aef42a9ffba3934303/common/output/writers.go#L464-L500","documentation":"NewJSONWriter creates (truncating) the main output file and returns this error when os.OpenFile fails. Without the main JSON file the writer cannot be constructed, so the constructor aborts and returns the wrapped OS error.","triggerScenarios":"os.OpenFile(filePath, O_CREATE|O_WRONLY|O_TRUNC) fails: nonexistent parent directory, no write permission, filePath is a directory, or too many open files.","commonSituations":"Config points to a directory path like ./out/ instead of a file; output directory never created before calling NewJSONWriter; running under a user lacking permission on the target dir; path contains invalid characters.","solutions":["os.MkdirAll(filepath.Dir(filePath), 0o755) before calling NewJSONWriter","Verify filePath is a file path, not an existing directory","Check write permissions for the process user on the target directory","Inspect the wrapped error (ENOSPC/EACCES/ENOENT) for the specific cause","Check ulimit -n if many files are open simultaneously"],"exampleFix":"// before\nw, err := output.NewJSONWriter(\"./results/out.json\")\n// after\nif err := os.MkdirAll(filepath.Dir(\"./results/out.json\"), 0o755); err != nil {\n\treturn err\n}\nw, err := output.NewJSONWriter(\"./results/out.json\")","handlingStrategy":"validation","validationCode":"if err := os.MkdirAll(filepath.Dir(filePath), 0o755); err != nil { return err }\nif fi, err := os.Stat(filePath); err == nil && fi.IsDir() { return fmt.Errorf(\"path is a directory: %s\", filePath) }\nprobe, err := os.OpenFile(filePath, os.O_CREATE|os.O_WRONLY, 0o644)\nif err != nil { return err }\nprobe.Close()","typeGuard":null,"tryCatchPattern":"w, err := output.NewJSONWriter(path)\nif err != nil {\n\tvar pe *fs.PathError\n\tif errors.As(err, &pe) && errors.Is(pe.Err, syscall.ENOENT) {\n\t\tos.MkdirAll(filepath.Dir(path), 0o755)\n\t\tw, err = output.NewJSONWriter(path)\n\t}\n\tif err != nil { return err }\n}","preventionTips":["Always create the output directory before constructing writers","Validate configured output paths at startup (writable, file not dir)","Run the process with a user that owns or can write the output dir","Fail fast on bad config with a pre-flight write probe","Watch open-file limits in multi-writer setups"],"tags":["go","file-io","initialization"],"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"}