{"record":{"id":"7748ee126c760a8c","repo":"RocketChat/Rocket.Chat","slug":"error-fetching-chart-data","errorCode":null,"errorMessage":"Error! fetching chart data.","messagePattern":"Error! fetching chart data\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"apps/meteor/client/views/omnichannel/analytics/InterchangeableChart.tsx","lineNumber":85,"sourceCode":"\t\t\t\tname: string;\n\t\t\t};\n\t\t\tdepartmentId?: string;\n\t\t}) => {\n\t\t\ttry {\n\t\t\t\tconst tooltipCallbacks = getChartTooltips(chartName);\n\t\t\t\tif (!params?.daterange?.from || !params?.daterange?.to) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\tconst result = await loadData({\n\t\t\t\t\tchartName,\n\t\t\t\t\tstart,\n\t\t\t\t\tend,\n\t\t\t\t\t...(departmentId && { departmentId }),\n\t\t\t\t});\n\n\t\t\t\tif (!result?.dataLabels || !result?.dataPoints) {\n\t\t\t\t\tthrow new Error('Error! fetching chart data.');\n\t\t\t\t}\n\t\t\t\t(context.current || typeof context.current === 'undefined') &&\n\t\t\t\t\tcanvas.current &&\n\t\t\t\t\t(context.current = await drawLineChart(\n\t\t\t\t\t\tcanvas.current,\n\t\t\t\t\t\tcontext.current,\n\t\t\t\t\t\t[result.chartLabel],\n\t\t\t\t\t\tresult.dataLabels,\n\t\t\t\t\t\t[result.dataPoints],\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\ttooltipCallbacks,\n\t\t\t\t\t\t},\n\t\t\t\t\t));\n\t\t\t} catch (error) {\n\t\t\t\tdispatchToastMessage({ type: 'error', message: error });\n\t\t\t}\n\t\t},\n\t);","sourceCodeStart":67,"sourceCodeEnd":103,"githubUrl":"https://github.com/RocketChat/Rocket.Chat/blob/b263243745917337314259cf987c0e989cf0cdc9/apps/meteor/client/views/omnichannel/analytics/InterchangeableChart.tsx#L67-L103","documentation":"Client-side data-integrity check in the omnichannel analytics InterchangeableChart: after loading chart data via loadData (the live/analytics metrics method), it requires both dataLabels and dataPoints to be present; a malformed or empty result throws new Error('Error! fetching chart data.'). The chart only draws when the backend returned a well-formed { chartLabel, dataLabels, dataPoints } object, so this guards against half-empty analytics responses.","triggerScenarios":"Opening Omnichannel Analytics with a date range where the queried period has no conversations (empty metrics arrays), or when the analytics method returns an object missing dataLabels/dataPoints; only runs when daterange.from and daterange.to are set.","commonSituations":"Fresh installs with no omnichannel traffic in the selected range; MongoDB aggregation returning empty labels/points; date-range pickers producing windows outside existing data.","solutions":["Select a date range that actually contains omnichannel conversations.","Confirm the analytics source (Analytics settings, Conversations/Convo metrics) has data for that period.","If data exists but charts still fail, inspect the analytics method response shape (dataLabels/dataPoints) for a backend regression.","As a code-level fix, throw only when the response exists but is malformed, and render an empty-chart state for genuinely empty periods."],"exampleFix":"// before\nif (!result?.dataLabels || !result?.dataPoints) {\n  throw new Error('Error! fetching chart data.');\n}\n\n// after: distinguish empty from malformed\nif (!result) throw new Error('Error! fetching chart data.');\nif (!result.dataLabels?.length && !result.dataPoints?.length) {\n  return; // render empty-chart placeholder for periods with no data\n}","handlingStrategy":"try-catch","validationCode":"if (!params?.daterange?.from || !params?.daterange?.to) return; // range required\n// prefer ranges that contain omnichannel traffic on fresh installs","typeGuard":"const isChartResult = (r: unknown): r is { chartLabel: string; dataLabels: unknown[]; dataPoints: unknown[] } =>\n  Boolean(r && Array.isArray((r as any).dataLabels) && Array.isArray((r as any).dataPoints));","tryCatchPattern":"try { await loadAndDraw(); } catch (e) { if ((e as Error).message === 'Error! fetching chart data.') { /* show 'no data for range' hint */ return; } throw e; }","preventionTips":["Default analytics ranges to periods with data.","Validate the metrics response shape in dev builds.","Distinguish empty periods from malformed responses in chart loaders."],"tags":["rocket-chat","omnichannel","analytics","chartjs"],"backgroundTag":"malformed-response-shape","analyzedSha":"b263243745917337314259cf987c0e989cf0cdc9","analyzedAt":"2026-08-18T15:26:39.429Z","contentChangedAt":"2026-08-18T15:26:39.429Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}