{"record":{"id":"659efb3911652e7b","repo":"RocketChat/Rocket.Chat","slug":"result-error","errorCode":null,"errorMessage":"result.error","messagePattern":"result\\.error","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/client/hooks/useEndpointUploadMutation.ts","lineNumber":27,"sourceCode":"\tendpoint: TPathPattern,\n\toptions?: UseEndpointUploadOptions<TData>,\n) => {\n\tconst sendData = useUpload(endpoint as PathFor<'POST'>);\n\tconst dispatchToastMessage = useToastMessageDispatch();\n\n\treturn useMutation({\n\t\tmutationFn: async (formData: FormData): Promise<TData> => {\n\t\t\tconst data = sendData(formData);\n\t\t\tconst promise = data instanceof Promise ? data : data.promise;\n\t\t\tconst result = await promise;\n\n\t\t\tif (!result.success) {\n\t\t\t\tif (result.status) {\n\t\t\t\t\tthrow new Error(result.status);\n\t\t\t\t}\n\n\t\t\t\tif (typeof result.error === 'string') {\n\t\t\t\t\tthrow new Error(result.error);\n\t\t\t\t}\n\n\t\t\t\tthrow new Error(t('FileUpload_Error'));\n\t\t\t}\n\t\t\treturn result as TData;\n\t\t},\n\t\tonError: (error) => {\n\t\t\tdispatchToastMessage({ type: 'error', message: error });\n\t\t},\n\t\t...options,\n\t});\n};\n","sourceCodeStart":9,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/client/hooks/useEndpointUploadMutation.ts#L9-L40","documentation":"Thrown by useEndpointUploadMutation as the second-priority branch: the upload failed (success === false), there is no usable `status` string, but result.error is a string. The hook rethrows that string as the Error message so the server-supplied reason reaches the user toast. This path exists because some upload endpoints populate `error` instead of `status`.","triggerScenarios":"The upload endpoint returns a body such as { success: false, status: '', error: 'You must be logged in to do this' } or { success: false, error: '[error-not-allowed]' }. The `status` field is empty/undefined while `error` is a populated string, so control falls to the `typeof result.error === 'string'` branch.","commonSituations":"Session expired mid-upload so the endpoint returns an auth error string in `error` with an empty status; a custom apps-engine upload handler that rejects via throw new Meteor.Error with only a reason string; legacy upload routes that never populated the `status` field.","solutions":["Read the toast text — it is result.error verbatim; auth-related strings point to a session/permission problem.","If the message looks like an auth error, force a re-login or re-fetch the auth token before retrying the upload.","If a custom app intercepts the upload, check its handler returns a proper status; update it to set result.status for consistency.","For legacy endpoints, verify the server version returns the UploadResult shape; upgrade the server if the error/status contract is missing."],"exampleFix":"// The hook already branches on result.error; callers just need to handle it:\ntry {\n  await upload.mutateAsync(formData);\n} catch (e) {\n  // e.message === the server's result.error string\n  if (e.message.includes('logged in')) {\n    redirectToLogin();\n  }\n}","handlingStrategy":"try-catch","validationCode":"// Ensure session is valid before uploading\nif (!Meteor.userId() || !Meteor.loggedIn()) {\n  throw new Error('Session expired');\n}","typeGuard":"function hasStringError(r: UploadResult): r is UploadResult & { error: string } {\n  return !r.success && typeof (r as any).error === 'string';\n}","tryCatchPattern":"try {\n  await upload.mutateAsync(formData);\n} catch (e) {\n  const msg = (e as Error).message; // equals result.error\n  if (msg.includes('logged in')) { redirectToLogin(); }\n}","preventionTips":["Refresh the auth token before retrying uploads after long idle periods.","Ensure apps-engine upload interceptors populate both status and error.","Log the raw response body server-side so empty statuses are diagnosable."],"tags":["file-upload","mutation","server-response","auth"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}