{"record":{"id":"6bf0b92bb7c144e2","repo":"router-for-me/CLIProxyAPI","slug":"failed-to-open-uploaded-file-w","errorCode":null,"errorMessage":"failed to open uploaded file: %w","messagePattern":"failed to open uploaded file: %w","errorType":"http","errorClass":null,"httpStatus":500,"severity":"warning","filePath":"internal/api/handlers/management/auth_files_crud.go","lineNumber":247,"sourceCode":"\n\theaders := make([]*multipart.FileHeader, 0)\n\tfor _, key := range keys {\n\t\theaders = append(headers, form.File[key]...)\n\t}\n\treturn headers, nil\n}\n\nfunc (h *Handler) storeUploadedAuthFile(ctx context.Context, file *multipart.FileHeader) (string, error) {\n\tif file == nil {\n\t\treturn \"\", fmt.Errorf(\"no file uploaded\")\n\t}\n\tname := filepath.Base(strings.TrimSpace(file.Filename))\n\tif !strings.HasSuffix(strings.ToLower(name), \".json\") {\n\t\treturn \"\", errAuthFileMustBeJSON\n\t}\n\tsrc, err := file.Open()\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to open uploaded file: %w\", err)\n\t}\n\tdefer src.Close()\n\n\tdata, err := io.ReadAll(src)\n\tif err != nil {\n\t\treturn \"\", fmt.Errorf(\"failed to read uploaded file: %w\", err)\n\t}\n\tif err := h.writeAuthFile(ctx, name, data); err != nil {\n\t\treturn \"\", err\n\t}\n\treturn name, nil\n}\n\nfunc (h *Handler) writeAuthFile(ctx context.Context, name string, data []byte) error {\n\tdst := filepath.Join(h.cfg.AuthDir, filepath.Base(name))\n\tif !filepath.IsAbs(dst) {\n\t\tif abs, errAbs := filepath.Abs(dst); errAbs == nil {\n\t\t\tdst = abs","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/auth_files_crud.go#L229-L265","documentation":"After confirming a file part exists, storeUploadedAuthFile calls file.Open() to get a reader for the uploaded multipart file. If Open() fails it returns `failed to open uploaded file: %w`. In Go's mime/multipart this is rare: it fails when the underlying temp file or memory buffer backing the part became unavailable (e.g. temp dir cleaned mid-request, part data corrupted) — not for user-format problems, which are caught earlier by the .json suffix check.","triggerScenarios":"Multipart part exceeding memory buffering and its temp file removed (TMPDIR cleaned or tmpfs reaped while the request was in flight); very large uploads hitting server temp constraints; OS-level file descriptor exhaustion preventing the temp file reopen.","commonSituations":"Oversized auth file uploads on containers with tiny /tmp; concurrent heavy uploads exhausting FDs; hosting platforms aggressively purging temp files.","solutions":["Retry the upload — transient temp-file loss usually clears immediately.","Reduce the upload size (auth files are small KB JSON; a huge file suggests the wrong file is attached).","Check TMPDIR free space and fd limits (ulimit -n) on the server if failures repeat.","Inspect the wrapped error for the OS cause before changing anything else."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":"func isUploadOpenFailure(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"failed to open uploaded file\")\n}","tryCatchPattern":"if isUploadOpenFailure(err) {\n    time.Sleep(time.Second)\n    err = uploadAgain(file) // temp-file loss is transient\n}","preventionTips":["Keep uploads small (auth files are KB JSON) to stay in memory buffering.","Maintain adequate /tmp space and fd limits on the server.","Treat repeat occurrences as an environment problem, not a client problem."],"tags":["management-api","upload","multipart","environment"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}