{"record":{"id":"ab7d13a808907f2b","repo":"RocketChat/Rocket.Chat","slug":"invalid-description","errorCode":null,"errorMessage":"Invalid description","messagePattern":"Invalid description","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/meteor/app/apps/server/bridges/moderation.ts","lineNumber":22,"sourceCode":"import type { IUser } from '@rocket.chat/apps-engine/definition/users';\nimport { ModerationReports } from '@rocket.chat/models';\n\nimport { reportMessage } from '../../../../server/lib/moderation/reportMessage';\n\nexport class AppModerationBridge extends ModerationBridge {\n\tconstructor(private readonly orch: IAppServerOrchestrator) {\n\t\tsuper();\n\t}\n\n\tprotected async report(messageId: IMessage['id'], description: string, userId: string, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is creating a new report.`);\n\n\t\tif (!messageId) {\n\t\t\tthrow new Error('Invalid message id');\n\t\t}\n\n\t\tif (!description) {\n\t\t\tthrow new Error('Invalid description');\n\t\t}\n\n\t\tawait reportMessage(messageId, description, userId || 'rocket.cat');\n\t}\n\n\tprotected async dismissReportsByMessageId(messageId: IMessage['id'], reason: string, action: string, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is dismissing reports by message id.`);\n\n\t\tif (!messageId) {\n\t\t\tthrow new Error('Invalid message id');\n\t\t}\n\n\t\tawait ModerationReports.hideMessageReportsByMessageId(messageId, appId, reason, action);\n\t}\n\n\tprotected async dismissReportsByUserId(userId: IUser['id'], reason: string, action: string, appId: string): Promise<void> {\n\t\tthis.orch.debugLog(`The App ${appId} is dismissing reports by user id.`);\n","sourceCodeStart":4,"sourceCodeEnd":40,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/f9d3ec372bb580fa8d036f94cf03925a478ef768/apps/meteor/app/apps/server/bridges/moderation.ts#L4-L40","documentation":"Thrown by AppModerationBridge.report when description is falsy. The bridge enforces a non-empty human description before forwarding to reportMessage, which itself rejects whitespace-only descriptions with 'error-invalid-description'. This guard is the cheap presence check.","triggerScenarios":"An App calls report with description undefined, null or '' — e.g. reporting from a one-tap 'report' button that sends no reason text, or passing a description variable that was never assigned from the UI payload.","commonSituations":"UX flows that allow reporting without collecting a reason; forgotten required field in a modal handler; description built from an optional form field that defaulted to undefined.","solutions":["Collect a non-empty reason from the user before calling report and validate it client-side in the App's UIKit handler.","Provide a sensible default description when the user submits none, e.g. `description = description || 'Reported via app';` — but note reportMessage will still reject pure whitespace, so trim and check length.","Skip the report call entirely if the description is empty rather than letting the bridge throw."],"exampleFix":"// before\nawait moderation.report(messageId, '', userId, appId);\n\n// after\nconst reason = (description || '').trim() || 'No reason provided';\nawait moderation.report(messageId, reason, userId, appId);","handlingStrategy":"validation","validationCode":"const reason = (typeof description === 'string' ? description : '').trim();\nif (reason.length === 0) {\n  throw new Error('A non-empty description is required to report');\n}\nawait moderation.report(messageId, reason, userId, appId);","typeGuard":"function isNonEmptyDescription(value: unknown): value is string {\n  return typeof value === 'string' && value.trim().length > 0;\n}","tryCatchPattern":null,"preventionTips":["Make the description a required field in your report modal and validate before submission.","Provide a meaningful default reason when the user submits none, but never pass an empty string.","Trim and check length, not just truthiness — reportMessage rejects whitespace-only descriptions."],"tags":["apps-engine","moderation-bridge","validation","description","truthy-check"],"backgroundTag":null,"analyzedSha":"f9d3ec372bb580fa8d036f94cf03925a478ef768","analyzedAt":"2026-08-12T19:07:17.372Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}