thingsboard/thingsboard · error · Error

Unsupported unit: ${from}

Error message

Unsupported unit: ${from}

What it means

Thrown by ThingsBoard's unit conversion service (unit.models.ts) when the source ('from') unit cannot be resolved by getUnit(). Units are looked up against the convert-units measure definitions; an unknown abbreviation/name yields a falsy origin and this Error. It usually surfaces from widget/legend unit conversion on dashboards.

Source

Thrown at ui-ngx/src/app/shared/models/unit.models.ts:456

  constructor(
    measures: Record<AllMeasures, TbMeasure<AllMeasuresUnits>>,
    unitCache: UnitCache
  ) {
    this.measureData = measures;
    this.unitCache = unitCache;
  }

  getUnitConverter(from: AllMeasuresUnits | string, to: AllMeasuresUnits | string): TbUnitConverter {
    return (value: number) => this.convert(value, from, to);
  }

  convert(value: number, from: AllMeasuresUnits | string, to: AllMeasuresUnits | string): number {
    const origin = this.getUnit(from);
    const destination = this.getUnit(to);

    if (!origin) {
      throw new Error(`Unsupported unit: ${from}`);
    }
    if (!destination) {
      throw new Error(`Unsupported unit: ${to}`);
    }
    if (origin.abbr === destination.abbr) {
      return value;
    }
    if (destination.measure !== origin.measure) {
      throw Error(`Cannot convert incompatible measures: ${origin.measure} to ${destination.measure}`);
    }
    let result = value * origin.unit.to_anchor;
    if (origin.unit.anchor_shift) {
      result -= origin.unit.anchor_shift;
    }
    if (typeof origin.unit.transform === 'function') {
      result = origin.unit.transform(result);
    }
    if (origin.system !== destination.system) {

View on GitHub (pinned to 45c30e83fa)

Solutions

  1. Check the exact 'from' string against supported values (see AllMeasuresUnits in unit.models.ts / the convert-units library measures).
  2. Fix typos or use the canonical abbreviation (e.g. 'C' not '°C', 'kWh' not 'kWH').
  3. If it is a custom unit, register it via the UnitSetConfigurator/units extension point before converting.
  4. Skip conversion entirely when from === to or when the unit is unknown to the registry.

Example fix

// before
const c = unitsService.getUnitConverter(widgetUnit, targetUnit);
c(value);

// after: verify unit exists before converting
const origin = unitsService.getUnit(widgetUnit);
if (!origin) { return value; } // or skip conversion in widget settings
const c = unitsService.getUnitConverter(widgetUnit, targetUnit);
Defensive patterns

Strategy: validation

Validate before calling

// before building a converter
if (!unitsService.getUnit(fromUnit)) {
  // skip conversion, log unit string, keep raw value
  return of(rawValue);
}
const convert = unitsService.getUnitConverter(fromUnit, toUnit);

Type guard

function isSupportedUnit(u: string): boolean {
  return unitsService.getUnit(u) != null;
}

Try / catch

try {
  result = unitsService.convert(value, from, to);
} catch (e: any) {
  if (e instanceof Error && e.message.startsWith('Unsupported unit')) {
    // fall back to raw value and surface a config warning
    result = value;
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling convert()/getUnitConverter() with a 'from' string not present in the unit registry: a typo like 'Celcius', a localized unit symbol, an empty string, or a custom unit abbreviation never registered via UnitSetConfigurator.

Common situations: Dashboard widget datasource or legend configured with a custom/misspelled unit; data from devices sending unusual unit strings; upgrading ThingsBoard where supported unit lists changed; telemetry unit metadata containing '%' or '' handled as convertible units.

Related errors


AI-assisted analysis of thingsboard/thingsboard@45c30e83fa (2026-08-14). Data as JSON: /api/errors/2565ffc4792962d8. Report an issue: GitHub.