{"record":{"id":"65d88119a3bdcb8f","repo":"RocketChat/Rocket.Chat","slug":"invalid-chart-name","errorCode":null,"errorMessage":"invalid-chart-name","messagePattern":"invalid-chart-name","errorType":"exception","errorClass":"Error","httpStatus":400,"severity":"error","filePath":"apps/meteor/server/api/v1/omnichannel/statistics.ts","lineNumber":20,"sourceCode":"import { isLivechatAnalyticsAgentOverviewProps, isLivechatAnalyticsOverviewProps } from '@rocket.chat/rest-typings';\n\nimport { API } from '../..';\nimport { getAgentOverviewDataCached, getAnalyticsOverviewDataCached } from '../../../lib/omnichannel/AnalyticsTyped';\nimport { settings } from '../../../settings';\n\nAPI.v1.addRoute(\n\t'livechat/analytics/agent-overview',\n\t{\n\t\tauthRequired: true,\n\t\tpermissionsRequired: ['view-livechat-manager'],\n\t\tvalidateParams: isLivechatAnalyticsAgentOverviewProps,\n\t},\n\t{\n\t\tasync get() {\n\t\t\tconst { name, departmentId, from, to } = this.queryParams;\n\n\t\t\tif (!name) {\n\t\t\t\tthrow new Error('invalid-chart-name');\n\t\t\t}\n\n\t\t\tconst user = await Users.findOneById(this.userId, { projection: { _id: 1, utcOffset: 1 } });\n\t\t\treturn API.v1.success(\n\t\t\t\tawait getAgentOverviewDataCached({\n\t\t\t\t\tdepartmentId,\n\t\t\t\t\tutcOffset: user?.utcOffset || 0,\n\t\t\t\t\tdaterange: { from, to },\n\t\t\t\t\tchartOptions: { name },\n\t\t\t\t\texecutedBy: this.userId,\n\t\t\t\t}),\n\t\t\t);\n\t\t},\n\t},\n);\n\nAPI.v1.addRoute(\n\t'livechat/analytics/overview',","sourceCodeStart":2,"sourceCodeEnd":38,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/2a7de457074cbb4d4373fbd9a4e5bea292c9c764/apps/meteor/server/api/v1/omnichannel/statistics.ts#L2-L38","documentation":"Thrown by GET /api/v1/livechat/analytics/agent-overview when the `name` query parameter is missing or empty. The route's param schema treats name as optional, so validation passes, but the handler then requires it to select which agent-overview chart to compute. Valid names are the agent overview chart actions: Total_conversations, Avg_chat_duration, Total_messages, Avg_first_response_time, Best_first_response_time, Avg_response_time, Avg_reaction_time (apps/meteor/server/services/omnichannel-analytics/AgentData.ts:44). A present-but-unknown name does NOT throw — it returns 200 with an empty body.","triggerScenarios":"GET /api/v1/livechat/analytics/agent-overview?from=2024-01-01&to=2024-01-31 with no name, or name= (empty string). Happens when a dashboard client builds the chart list dynamically and requests metadata without a selected chart.","commonSituations":"Custom dashboard integrations that iterate charts and accidentally issue one request with an unset name; scripts copied from docs where name was on a wrapped line and got dropped.","solutions":["Include a valid chart name: GET /api/v1/livechat/analytics/agent-overview?from=2024-01-01&to=2024-01-31&name=Total_conversations","Use one of the exact snake_case names: Total_conversations, Avg_chat_duration, Total_messages, Avg_first_response_time, Best_first_response_time, Avg_response_time, Avg_reaction_time","Remember the caller needs the view-livechat-manager permission or you get 403 before this check"],"exampleFix":"// before\nrequest.get(api('livechat/analytics/agent-overview')).query({ from, to });\n// after\nrequest.get(api('livechat/analytics/agent-overview')).query({ from, to, name: 'Total_conversations' });","handlingStrategy":"validation","validationCode":"const AGENT_CHARTS = ['Total_conversations','Avg_chat_duration','Total_messages','Avg_first_response_time','Best_first_response_time','Avg_response_time','Avg_reaction_time'] as const;\nconst name = AGENT_CHARTS.includes(selected) ? selected : AGENT_CHARTS[0];\nawait fetch(`${server}/api/v1/livechat/analytics/agent-overview?from=${from}&to=${to}&name=${name}`, { headers });","typeGuard":"const AGENT_CHART_NAMES = new Set(['Total_conversations','Avg_chat_duration','Total_messages','Avg_first_response_time','Best_first_response_time','Avg_response_time','Avg_reaction_time']);\nconst isAgentChartName = (n: string | undefined): n is string => !!n && AGENT_CHART_NAMES.has(n);","tryCatchPattern":"if (!name) throw new TypeError('chart name required'); // fail fast client-side\nconst body = await (await fetch(url, { headers })).json();\nif (!body.success && body.error === 'invalid-chart-name') { /* re-ask user to pick a chart */ }","preventionTips":["Model chart names as a const tuple in your client, not free strings","Never issue the request until a chart is selected in the UI"],"tags":["rest-api","livechat","analytics","query-params","validation"],"backgroundTag":"missing-required-argument","analyzedSha":"2a7de457074cbb4d4373fbd9a4e5bea292c9c764","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}