Stirling-Tools/Stirling-PDF · error · Error
Unsupported unit
Error message
Unsupported unit: ${unit} What it means
Thrown by calculateScaleFactor after normalizeUnit(unit) (lowercase + trim) is not a key of POINT_TO_UNIT. Supported units are exactly m, cm, mm, km, ft, in, yd, mi. Any other string (including 'inch', 'meter', 'pixel', or whitespace variants not collapsed by trim) triggers it.
Solutions
- Always pass canonical unit codes (m, cm, mm, km, ft, in, yd, mi) — keep display labels separate from stored values.
- Call getUnitFactor(unit) first; if it returns undefined, surface a friendly error before hitting calculateScaleFactor.
- Add a unit picker UI constrained to the known MeasurementUnit type so free text never reaches the function.
- Extend normalizeUnit to handle common aliases if you control the inputs.
Example fix
// before
calculateScaleFactor(ratio, userTypedUnit);
// after
const validUnits = ["m", "cm", "mm", "km", "ft", "in", "yd", "mi"] as const;
if (!validUnits.includes(userTypedUnit.toLowerCase().trim() as never)) {
throw new Error(`Unknown unit "${userTypedUnit}". Use one of: ${validUnits.join(", ")}`);
}
calculateScaleFactor(ratio, userTypedUnit); Defensive patterns
Strategy: validation
Validate before calling
const SUPPORTED_UNITS = Object.keys(POINT_TO_UNIT);
if (!SUPPORTED_UNITS.includes(unit.toLowerCase().trim())) {
throw new Error(`Unsupported unit "${unit}". Use: ${SUPPORTED_UNITS.join(", ")}`);
}
calculateScaleFactor(ratio, unit); Type guard
function isMeasurementUnit(unit: string): unit is MeasurementUnit {
return Object.hasOwn(POINT_TO_UNIT, unit.toLowerCase().trim());
} Prevention
- Store canonical unit codes (m, cm, mm, km, ft, in, yd, mi), never display labels, in config.
- Bind the unit picker to the MeasurementUnit type so free text cannot reach the helper.
- Pre-check getUnitFactor(unit) before calling calculateScaleFactor.
When it happens
Trigger: Calling calculateScaleFactor(1, 'inch'); passing a localized full unit name ('centimeters'); a unit pulled from a persisted config that was saved with an unexpected token; trailing/internal whitespace normalizeUnit does not collapse (e.g. 'c m').
Common situations: i18n: storing display labels instead of canonical unit codes; migrating from an older unit list; third-party plugin reusing the helper with its own unit vocabulary.
Related errors
- Invalid real-world distance (must be positive)
- Invalid PDF distance (must be positive)
- Invalid scale ratio
- Default team not found
- Email missing for this user. Please contact support for…
AI-assisted analysis of Stirling-Tools/Stirling-PDF@9ef20dcab8 (2026-08-13).
Data as JSON: /api/errors/02031a97d4e82056.
Report an issue: GitHub.
Appendix: source
Thrown at frontend/editor/src/core/utils/measurementUtils.ts:51
return Object.hasOwn(POINT_TO_UNIT, unit);
}
export function getUnitFactor(unit: string): number | undefined {
const normalized = normalizeUnit(unit);
if (!isMeasurementUnit(normalized)) {
return undefined;
}
return POINT_TO_UNIT[normalized];
}
export function calculateScaleFactor(ratio: number, unit: string): number {
if (!Number.isFinite(ratio) || ratio <= 0) {
throw new Error(`Invalid scale ratio: ${ratio}`);
}
const normalized = normalizeUnit(unit);
if (!isMeasurementUnit(normalized)) {
throw new Error(`Unsupported unit: ${unit}`);
}
return POINT_TO_UNIT[normalized] * ratio;
}
export function generateScaleLabel(ratio: number | null, unit: string): string {
if (ratio === null || ratio === undefined) {
return unit;
}
const display = Number.isInteger(ratio)
? ratio.toString()
: ratio.toFixed(2).replace(/\.?0+$/, "");
return `1:${display} (${unit})`;
}
// Imperial units
const IMPERIAL_UNITS = ["ft", "in", "yd", "mi"] as const;
export function isImperialUnit(unit: string): boolean {View on GitHub (pinned to 9ef20dcab8)