{"id":"709010365c336a70","repo":"gofiber/fiber","slug":"failed-to-create-file-w","errorCode":null,"errorMessage":"failed to create file: %w","messagePattern":"failed to create file: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"client/response.go","lineNumber":164,"sourceCode":"\tcase string:\n\t\tfile := filepath.Clean(p)\n\t\tdir := filepath.Dir(file)\n\n\t\t// Create directory if it doesn't exist\n\t\tif _, err := os.Stat(dir); err != nil {\n\t\t\tif !errors.Is(err, fs.ErrNotExist) {\n\t\t\t\treturn fmt.Errorf(\"failed to check directory: %w\", err)\n\t\t\t}\n\n\t\t\tif err = os.MkdirAll(dir, 0o750); err != nil {\n\t\t\t\treturn fmt.Errorf(\"failed to create directory: %w\", err)\n\t\t\t}\n\t\t}\n\n\t\t// Create and write to file\n\t\toutFile, err := os.Create(file)\n\t\tif err != nil {\n\t\t\treturn fmt.Errorf(\"failed to create file: %w\", err)\n\t\t}\n\t\tdefer func() { _ = outFile.Close() }() //nolint:errcheck // not needed\n\n\t\t// Use BodyStream() which handles both streaming and non-streaming cases\n\t\tif _, err = io.Copy(outFile, r.BodyStream()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write response body to file: %w\", err)\n\t\t}\n\n\t\treturn nil\n\n\tcase io.Writer:\n\t\t// Use BodyStream() which handles both streaming and non-streaming cases\n\t\tif _, err := io.Copy(p, r.BodyStream()); err != nil {\n\t\t\treturn fmt.Errorf(\"failed to write response body to writer: %w\", err)\n\t\t}\n\t\t// Close the writer if it implements io.WriteCloser\n\t\tif pc, ok := p.(io.WriteCloser); ok {\n\t\t\t_ = pc.Close() //nolint:errcheck // not needed","sourceCodeStart":146,"sourceCodeEnd":182,"githubUrl":"https://github.com/gofiber/fiber/blob/9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c/client/response.go#L146-L182","documentation":"Returned by Response.Save (client/response.go:164) when os.Create fails for the target file. After ensuring the parent directory exists, Save creates (or truncates) the file; failure — permission denied, invalid name, read-only filesystem, open-file limit — is wrapped here.","triggerScenarios":"Calling resp.Save(path) where path cannot be created: permission denied in the directory, the path names a directory, an invalid filename (e.g. containing '/' on the OS, or NUL), read-only filesystem, or the process has hit its file-descriptor limit.","commonSituations":"App user lacks write permission in the target directory; path points at an existing directory; container on a read-only layer; too many open files (ulimit -n); filename contains illegal characters from unsanitized input.","solutions":["Confirm the process can write in the target directory (permission bits / ownership).","Ensure the path does not name an existing directory and the filename is valid.","Raise the open-file ulimit if the process is exhausting descriptors.","Use a writable volume for output files."],"exampleFix":"// before — writing into a directory without write permission\nerr := resp.Save(\"/etc/app/out.json\")\n\n// after — write into a directory owned by the app user\nerr := resp.Save(\"/var/lib/myapp/out.json\")  // ensure /var/lib/myapp is writable","handlingStrategy":"validation","validationCode":"// Check the target file can be created before streaming.\nfunc canCreate(path string) error {\n    dir := filepath.Dir(path)\n    if info, err := os.Stat(dir); err != nil || !info.IsDir() {\n        return fmt.Errorf(\"parent dir unusable\")\n    }\n    // probe writability\n    tmp, err := os.CreateTemp(dir, \".probe-*\")\n    if err != nil {\n        return err\n    }\n    tmp.Close(); os.Remove(tmp.Name())\n    return nil\n}","typeGuard":null,"tryCatchPattern":"if err := resp.Save(path); err != nil {\n    if strings.Contains(err.Error(), \"failed to create file\") {\n        path = filepath.Join(os.TempDir(), filepath.Base(path))\n        return resp.Save(path)\n    }\n    return err\n}","preventionTips":["Write only into directories where the process has write permission.","Avoid filenames with illegal characters or that name existing directories.","Raise the open-file ulimit if the process exhausts descriptors."],"tags":["client","save","filesystem","os-create","permissions"],"analyzedSha":"9a4c7e57fe0b080a04235d28a4b0d2b4b353d58c","analyzedAt":"2026-08-04T21:44:03.395Z","schemaVersion":2}