{"record":{"id":"0df890ccbee850ed","repo":"router-for-me/CLIProxyAPI","slug":"auth-path-is-empty","errorCode":null,"errorMessage":"auth path is empty","messagePattern":"auth path is empty","errorType":"http","errorClass":null,"httpStatus":500,"severity":"error","filePath":"internal/api/handlers/management/auth_files_crud.go","lineNumber":466,"sourceCode":"\t\tid = strings.ToLower(id)\n\t}\n\treturn id\n}\n\nfunc (h *Handler) registerAuthFromFile(ctx context.Context, path string, data []byte) error {\n\tif h.authManager == nil {\n\t\treturn nil\n\t}\n\tauth, err := h.buildAuthFromFileData(path, data)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn h.upsertAuthRecord(ctx, auth)\n}\n\nfunc (h *Handler) buildAuthFromFileData(path string, data []byte) (*coreauth.Auth, error) {\n\tif path == \"\" {\n\t\treturn nil, fmt.Errorf(\"auth path is empty\")\n\t}\n\tif data == nil {\n\t\tvar err error\n\t\tdata, err = os.ReadFile(path)\n\t\tif err != nil {\n\t\t\treturn nil, fmt.Errorf(\"failed to read auth file: %w\", err)\n\t\t}\n\t}\n\tmetadata := make(map[string]any)\n\tif err := json.Unmarshal(data, &metadata); err != nil {\n\t\treturn nil, fmt.Errorf(\"invalid auth file: %w\", err)\n\t}\n\tprovider, _ := metadata[\"type\"].(string)\n\tif provider == \"\" {\n\t\tprovider = \"unknown\"\n\t}\n\tlabel := provider\n\tif email, ok := metadata[\"email\"].(string); ok && email != \"\" {","sourceCodeStart":448,"sourceCodeEnd":484,"githubUrl":"https://github.com/router-for-me/CLIProxyAPI/blob/78f0c4079e3e6273d65d03b5549cffc898703264/internal/api/handlers/management/auth_files_crud.go#L448-L484","documentation":"buildAuthFromFileData in auth_files_crud.go constructs a coreauth.Auth from a file path plus optional in-memory data. An empty path is rejected with `auth path is empty` because the resulting Auth record would have no resolvable file location — every later reload/delete/save of that credential keys off the path. It is a programmer/validation guard on the management API's internal file ingestion path.","triggerScenarios":"Calling writeAuthFile/upsertAuthFromFile with an empty string path: upload flow produced an empty filename (multipart part with empty filename after TrimSpace+Base), or internal code passed \"\" when persisting an auth record derived from a file.","commonSituations":"Multipart upload where the file part has no filename attribute (curl -F 'file=@-;filename=' tricks or programmatic clients); clients sending the file data in a field the handler does not treat as a file, leaving the derived name empty.","solutions":["Ensure uploaded file parts carry a real filename ending in .json (curl -F 'file=@my.json').","Client-side, reject empty filenames before uploading.","If invoking the SDK handler directly, always pass the absolute destination path under the configured authDir."],"exampleFix":"// before: part with no filename\nmultipart.append('file', blob)  // no filename -> empty name\n\n// after\nmultipart.append('file', blob, 'my-codex-auth.json')","handlingStrategy":"validation","validationCode":"func validUploadName(filename string) bool {\n    n := strings.TrimSpace(filename)\n    return n != \"\" && strings.HasSuffix(strings.ToLower(n), \".json\")\n}","typeGuard":"func isEmptyAuthPath(err error) bool {\n    return err != nil && strings.Contains(err.Error(), \"auth path is empty\")\n}","tryCatchPattern":null,"preventionTips":["Always attach uploads with an explicit .json filename.","When calling the SDK handler directly, pass the absolute destination path under authDir.","Reject empty filenames in client forms before submitting."],"tags":["management-api","validation","upload","auth-files"],"backgroundTag":null,"analyzedSha":"78f0c4079e3e6273d65d03b5549cffc898703264","analyzedAt":"2026-08-15T12:26:37.444Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}