alibaba/arthas · error · Error

Unsupported dataSource format ${format}

Error message

Unsupported dataSource format ${format}

What it means

Same vendored flame-graph Web Component as error 0, but the active copy lives under src/components/FlameGraph/flame-graph-class.js (the public/flame-graph/ copy is a duplicate). genFrames() compares this.$dataSource.format with === to the lowercase literals 'line'/'tree', while the setter validated using toLowerCase() and stored the original object, so a mixed-case format passes the setter and throws here.

Source

Thrown at labs/arthas-jfr-frontend/src/components/FlameGraph/flame-graph-class.js:479

  genFrames() {
    this.$root.clear();
    this.$stackTraceMaxDepth = 0;
    this.$totalWeight = 0;
    this.$totalWeightOfBaseline1 = 0;
    this.$totalWeightOfBaseline2 = 0;

    if (this.$dataSource) {
      let format = this.$dataSource.format;
      if (format === 'line') {
        this.genFramesFromLineData();
      } else if (format === 'tree') {
        if (this.$$reverse) {
          console.warn("Tree format data doesn't support reverse");
        }
        this.genFramesFromTreeData();
      } else {
        throw new Error(`Unsupported dataSource format ${format}`);
      }
    }

    this.$root.sort();

    this.$information = this.$$diff
      ? {
          totalWeight: this.$totalWeight,
          totalWeightOfBaseline1: this.$totalWeightOfBaseline1,
          totalWeightOfBaseline2: this.$totalWeightOfBaseline2
        }
      : {
          totalWeight: this.$totalWeight
        };

    this.$root.text = this.$$rootTextGenerator(this.$dataSource, this.$information);
  }

View on GitHub (pinned to 21cf2e9ba5)

Solutions

  1. Normalize to lowercase 'line' or 'tree' before assigning: String(format).trim().toLowerCase().
  2. Patch genFrames() in this src/components copy to use this.$dataSource.format.toLowerCase() (mirror the fix in public/ if both are loaded).
  3. Never mutate $dataSource.format after the setter; assign a fresh dataSource object instead.

Example fix

// before
el.dataSource = { format: rawFmt /* 'Tree' */, data };

// after
el.dataSource = { format: String(rawFmt).trim().toLowerCase(), data };
Defensive patterns

Strategy: validation

Validate before calling

function normalizeDataSource(ds) {
  if (!ds || typeof ds.format !== 'string') return null;
  const f = ds.format.trim().toLowerCase();
  return (f === 'line' || f === 'tree') ? { ...ds, format: f } : null;
}
const safe = normalizeDataSource(raw);
if (safe) el.dataSource = safe;

Type guard

function isLineOrTreeFormat(ds) {
  return !!ds && typeof ds.format === 'string' && ['line','tree'].includes(ds.format.trim().toLowerCase());
}

Try / catch

try { el.dataSource = raw; }
catch (e) { if (/Unsupported dataSource format/.test(e.message)) { el.dataSource = { ...raw, format: String(raw.format).trim().toLowerCase() }; } else throw e; }

Prevention

When it happens

Trigger: Assigning element.dataSource = { format: 'Line'/'TREE', ... }; mutating this.$dataSource.format after assignment; assigning $dataSource directly to bypass the setter.

Common situations: Backend returns capitalized format; the public/ and src/components/ copies drift and only one gets patched.

Related errors


AI-assisted analysis of alibaba/arthas@21cf2e9ba5 (2026-08-14). Data as JSON: /api/errors/11389a4161da83a8. Report an issue: GitHub.