{"record":{"id":"058d1527fed41f5a","repo":"RocketChat/Rocket.Chat","slug":"auth-option-should-be-of-the-form-username-passwo","errorCode":null,"errorMessage":"auth option should be of the form \"username:password\"","messagePattern":"auth option should be of the form \"username:password\"","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/http.ts","lineNumber":38,"sourceCode":"\t}\n\n\tprotected async call(info: IHttpBridgeRequestInfo): Promise<IHttpResponse> {\n\t\t// begin comptability with old HTTP.call API\n\t\tconst url = new URL(info.url);\n\n\t\tconst { request, method } = info;\n\n\t\tconst { headers = {} } = request;\n\n\t\tlet { content } = request;\n\n\t\tif (!content && typeof request.data === 'object') {\n\t\t\tcontent = request.data;\n\t\t}\n\n\t\tif (request.auth) {\n\t\t\tif (request.auth.indexOf(':') < 0) {\n\t\t\t\tthrow new Error('auth option should be of the form \"username:password\"');\n\t\t\t}\n\n\t\t\tconst base64 = Buffer.from(request.auth, 'ascii').toString('base64');\n\t\t\theaders.Authorization = `Basic ${base64}`;\n\t\t}\n\n\t\tlet paramsForBody;\n\n\t\tif (content || isGetOrHead(method)) {\n\t\t\tif (request.params) {\n\t\t\t\tObject.keys(request.params).forEach((key) => {\n\t\t\t\t\tif (request.params?.[key]) {\n\t\t\t\t\t\turl.searchParams.append(key, request.params?.[key]);\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tparamsForBody = request.params;","sourceCodeStart":20,"sourceCodeEnd":56,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0/apps/meteor/app/apps/server/bridges/http.ts#L20-L56","documentation":"FileSystem:UserDataFiles.get serves GDPR data-export downloads from the FileSystem store; when anything in the try throws (typically fsp.stat ENOENT — the export record exists but the exported file is gone from disk), it returns a bodyless 404. Like the avatars store, a stat that resolves non-file silently sends nothing.","triggerScenarios":"UserDataFiles document exists but the export file is missing: FileUpload_FileSystemPath changed since the export was generated; the export file was purged by cleanup jobs or the volume was recreated; DB restored without the exports directory.","commonSituations":"Expired export files after retention cleanup; storage migrations; volume mounting issues in containerized deployments; users clicking old export links from earlier emails.","solutions":["Confirm the export still exists at the computed path and that FileUpload_FileSystemPath has not changed","Regenerate the export for the user (the old link will not heal itself)","Add logging to the catch to distinguish ENOENT from permission failures"],"exampleFix":"// before\n} catch (e) {\n\tres.writeHead(404);\n\tres.end();\n}\n// after\n} catch (e) {\n\tSystemLogger.error({ msg: 'user-data file serve failed', fileId: file._id, code: e.code });\n\tres.writeHead(404);\n\tres.end();\n}","handlingStrategy":"validation","validationCode":"const p = await store.getFilePath(file._id, file);\nconst exists = await fsp.stat(p).then((s) => s.isFile()).catch(() => false);\nif (!exists) { /* tell the user to regenerate the export; do not link a dead file */ }","typeGuard":null,"tryCatchPattern":"Catch and log e.code for user-data file serving failures; ENOENT should mark the export record as expired/missing so the UI can offer regeneration rather than a naked 404.","preventionTips":["Expire export links when the underlying files are purged by retention jobs","Keep export generation and storage on the same volume lifecycle","Log fileId + code on every failed export download"],"tags":["file-upload","gdpr","user-data-export","filesystem","http-404"],"backgroundTag":"file-missing-from-storage","analyzedSha":"b2c16d5842cbe6b69b59bdf6fc5e5f1afcd1f0b0","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}