{"record":{"id":"724a831aaa6bc096","repo":"gofiber/fiber","slug":"w-q-w","errorCode":null,"errorMessage":"%w: %q: %w","messagePattern":"%w: %q: %w","errorType":"exception","errorClass":"ErrFileOpen","httpStatus":null,"severity":"error","filePath":"ctx.go","lineNumber":572,"sourceCode":"}\n\n// SaveFile saves any multipart file to disk.\nfunc (*DefaultCtx) SaveFile(fileheader *multipart.FileHeader, path string) error {\n\tif fileheader == nil {\n\t\treturn ErrFileHeaderNil\n\t}\n\treturn fasthttp.SaveMultipartFile(fileheader, path)\n}\n\n// SaveFileToStorage saves any multipart file to an external storage system.\nfunc (c *DefaultCtx) SaveFileToStorage(fileheader *multipart.FileHeader, path string, storage Storage) error {\n\tif fileheader == nil {\n\t\treturn ErrFileHeaderNil\n\t}\n\n\tfile, err := fileheader.Open()\n\tif err != nil {\n\t\treturn fmt.Errorf(\"%w: %q: %w\", ErrFileOpen, fileheader.Filename, err)\n\t}\n\tdefer file.Close() //nolint:errcheck // not needed\n\n\tmaxUploadSize := c.app.config.BodyLimit\n\tif maxUploadSize <= 0 {\n\t\tmaxUploadSize = DefaultBodyLimit\n\t}\n\n\tif fileheader.Size > 0 && fileheader.Size > int64(maxUploadSize) {\n\t\treturn fmt.Errorf(\"%w: %q: %w\", ErrFileRead, fileheader.Filename, fasthttp.ErrBodyTooLarge)\n\t}\n\n\tbuf := bytebufferpool.Get()\n\tdefer bytebufferpool.Put(buf)\n\n\tlimitedReader := io.LimitReader(file, int64(maxUploadSize)+1)\n\tif _, err = buf.ReadFrom(limitedReader); err != nil {\n\t\treturn fmt.Errorf(\"%w: %q: %w\", ErrFileRead, fileheader.Filename, err)","sourceCodeStart":554,"sourceCodeEnd":590,"githubUrl":"https://github.com/gofiber/fiber/blob/a105acad6c1e4576a77f01e02973f67e962bb58d/ctx.go#L554-L590","documentation":"Returned by Ctx.SaveFileToStorage when multipart.FileHeader.Open() fails while accessing the uploaded file's content. The error wraps the sentinel ErrFileOpen ('file: failed to open file'), the original filename, and the underlying OS/multipart error: 'file: failed to open file: \"report.pdf\": <err>'. This is an early failure in the save-to-storage pipeline, before size limiting or reading begins.","triggerScenarios":"Calling c.SaveFileToStorage(fileheader, path, storage) where the multipart header is present but its underlying part cannot be opened. The fileheader must be non-nil (a nil header returns ErrFileHeaderNil earlier).","commonSituations":"The upload was already consumed/drained by an earlier handler, the temp file backing the multipart part was deleted under the process, or the OS returned an I/O error opening the spilled part. Rare in normal operation; more likely in tests that hand-craft FileHeader values.","solutions":["Do not read or save the same multipart file twice; consume it once in a single handler.","Inspect the wrapped underlying error (errors.Unwrap / errors.Is(err, ErrFileOpen)) to identify the OS cause.","If reproducing in tests, build the FileHeader from real multipart data via a httptest request rather than a hand-constructed struct.","Handle the error with a 4xx/5xx response appropriate to the cause (client gone vs. server I/O)."],"exampleFix":"if err := c.SaveFileToStorage(fh, key, store); err != nil {\n    if errors.Is(err, fiber.ErrFileOpen) {\n        return c.Status(fiber.StatusBadGateway).SendString(\"could not open upload\")\n    }\n    return err\n}","handlingStrategy":"try-catch","validationCode":"null","typeGuard":"null","tryCatchPattern":"if err := c.SaveFileToStorage(fh, key, store); err != nil {\n    if errors.Is(err, fiber.ErrFileOpen) {\n        // underlying multipart part could not be opened\n        return fiber.NewError(fiber.StatusBadRequest, \"upload unavailable\")\n    }\n    return err\n}","preventionTips":["Consume each multipart file exactly once in a single handler.","Do not hand-construct multipart.FileHeader in tests; use a real httptest multipart request.","Branch on errors.Is(err, fiber.ErrFileOpen) to separate open failures from read/store failures.","Log the unwrapped underlying error to pinpoint OS causes."],"tags":["upload","multipart","storage","gofiber","filesystem"],"backgroundTag":null,"analyzedSha":"a105acad6c1e4576a77f01e02973f67e962bb58d","analyzedAt":"2026-08-11T17:33:26.942Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}