{"record":{"id":"024c423384086030","repo":"alibaba/arthas","slug":"unsupported-datasource-format-format","errorCode":null,"errorMessage":"Unsupported dataSource format ${format}","messagePattern":"Unsupported dataSource format (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"labs/arthas-jfr-frontend/public/flame-graph/flame-graph-class.js","lineNumber":479,"sourceCode":"\n  genFrames() {\n    this.$root.clear();\n    this.$stackTraceMaxDepth = 0;\n    this.$totalWeight = 0;\n    this.$totalWeightOfBaseline1 = 0;\n    this.$totalWeightOfBaseline2 = 0;\n\n    if (this.$dataSource) {\n      let format = this.$dataSource.format;\n      if (format === 'line') {\n        this.genFramesFromLineData();\n      } else if (format === 'tree') {\n        if (this.$$reverse) {\n          console.warn(\"Tree format data doesn't support reverse\");\n        }\n        this.genFramesFromTreeData();\n      } else {\n        throw new Error(`Unsupported dataSource format ${format}`);\n      }\n    }\n\n    this.$root.sort();\n\n    this.$information = this.$$diff\n      ? {\n          totalWeight: this.$totalWeight,\n          totalWeightOfBaseline1: this.$totalWeightOfBaseline1,\n          totalWeightOfBaseline2: this.$totalWeightOfBaseline2\n        }\n      : {\n          totalWeight: this.$totalWeight\n        };\n\n    this.$root.text = this.$$rootTextGenerator(this.$dataSource, this.$information);\n  }\n","sourceCodeStart":461,"sourceCodeEnd":497,"githubUrl":"https://github.com/alibaba/arthas/blob/21cf2e9ba52b305290be7223b980ff504bb9cb5b/labs/arthas-jfr-frontend/public/flame-graph/flame-graph-class.js#L461-L497","documentation":"Thrown by the flame-graph Web Component's genFrames() while rendering, when this.$dataSource.format is not exactly 'line' or 'tree'. Note the setter normalizes format with toLowerCase() for validation but stores the ORIGINAL dataSource object, so a format like 'Line' or 'TREE' passes the setter yet fails here because genFrames compares with === against the lowercase literals. It is a defensive guard that also catches direct mutation of $dataSource.format after assignment.","triggerScenarios":"Assigning element.dataSource = { format: 'Line'/'TREE'/' line ' , ... } (any case other than all-lowercase, or with surrounding whitespace); mutating this.$dataSource.format to an invalid value then calling render(); bypassing the dataSource setter and writing this.$dataSource directly.","commonSituations":"Backend/JFR service returns format with different casing than the component expects; data reused from a config file that capitalizes 'Tree'; the same vendored library is duplicated under public/flame-graph/ and src/components/FlameGraph/ so a fix in one copy does not fix the other.","solutions":["Normalize the format to a lowercase 'line' or 'tree' before assigning: dataSource.format = String(dataSource.format).trim().toLowerCase().","Patch genFrames() to read this.$dataSource.format.toLowerCase() so the render path matches the setter's validation (apply to BOTH public/ and src/components/ copies).","Ensure the value assigned is exactly the string 'line' or 'tree' and is never mutated after the setter runs."],"exampleFix":"// before\nel.dataSource = { format: 'Tree', data: tree };\n// throws: Unsupported dataSource format Tree\n\n// after\nel.dataSource = { format: 'tree', data: tree };\n// or normalize defensively\nconst ds = { ...raw, format: String(raw.format).trim().toLowerCase() };\nel.dataSource = ds;","handlingStrategy":"validation","validationCode":"function normalizeDataSource(ds) {\n  if (!ds || typeof ds.format !== 'string') return null;\n  const f = ds.format.trim().toLowerCase();\n  return (f === 'line' || f === 'tree') ? Object.assign({}, ds, { format: f }) : null;\n}\nconst safe = normalizeDataSource(raw);\nif (safe) el.dataSource = safe; else throw new Error('invalid dataSource format');","typeGuard":"function isLineOrTreeFormat(ds) {\n  return !!ds && typeof ds.format === 'string'\n    && ['line', 'tree'].includes(ds.format.trim().toLowerCase());\n}","tryCatchPattern":"try {\n  el.dataSource = raw;\n} catch (e) {\n  if (/Unsupported dataSource format/.test(e.message)) {\n    el.dataSource = Object.assign({}, raw, { format: String(raw.format).trim().toLowerCase() });\n  } else throw e;\n}","preventionTips":["Always lowercase the format before assigning dataSource.","Never mutate $dataSource.format after assignment.","Patch both the public/ and src/components/ copies of the component."],"tags":["flame-graph","web-component","data-validation","case-sensitivity"],"backgroundTag":null,"analyzedSha":"21cf2e9ba52b305290be7223b980ff504bb9cb5b","analyzedAt":"2026-08-14T00:57:07.243Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}