{"id":"bb87b2b97d2e2ffe","repo":"moment/moment","slug":"unknown-unit-units","errorCode":null,"errorMessage":"Unknown unit ${units}","messagePattern":"Unknown unit (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/lib/duration/as.js","lineNumber":43,"sourceCode":"    } else {\n        // handle milliseconds separately because of floating point math errors (issue #1867)\n        days = this._days + Math.round(monthsToDays(this._months));\n        switch (units) {\n            case 'week':\n                return days / 7 + milliseconds / 6048e5;\n            case 'day':\n                return days + milliseconds / 864e5;\n            case 'hour':\n                return days * 24 + milliseconds / 36e5;\n            case 'minute':\n                return days * 1440 + milliseconds / 6e4;\n            case 'second':\n                return days * 86400 + milliseconds / 1000;\n            // Math.floor prevents floating point math errors here\n            case 'millisecond':\n                return Math.floor(days * 864e5) + milliseconds;\n            default:\n                throw new Error('Unknown unit ' + units);\n        }\n    }\n}\n\nfunction makeAs(alias) {\n    return function () {\n        return this.as(alias);\n    };\n}\n\nvar asMilliseconds = makeAs('ms'),\n    asSeconds = makeAs('s'),\n    asMinutes = makeAs('m'),\n    asHours = makeAs('h'),\n    asDays = makeAs('d'),\n    asWeeks = makeAs('w'),\n    asMonths = makeAs('M'),\n    asQuarters = makeAs('Q'),","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/moment/moment/blob/019806b26f544e42c42bcaafba0bfd3c9066c7db/src/lib/duration/as.js#L25-L61","documentation":"Thrown by moment.duration(...).as(units) in src/lib/duration/as.js:43 when the resolved unit is not one moment can convert a duration into. normalizeUnits (src/lib/units/aliases.js:54) maps the input string to a canonical unit or returns undefined; the as() switch only handles ms/second/minute/hour/day/week and (in the month branch) month/quarter/year. Any other value falls through to the `default` and throws 'Unknown unit <units>'. Critically, calendar units like 'date', 'dayOfYear', 'weekday', 'isoWeekday', 'weekYear', 'isoWeekYear', 'isoWeek' ARE in the aliases table, so they normalize successfully but are NOT valid for durations and still hit this throw.","triggerScenarios":"Calling duration.as() with (a) a typo'd unit string e.g. dur.as('minut') -> normalizeUnits returns undefined -> throws 'Unknown unit undefined'; (b) no argument or a non-string e.g. dur.as() or dur.as(5) -> undefined -> throws 'Unknown unit undefined'; (c) a calendar-only unit e.g. dur.as('date') or dur.as('D') -> normalizes to 'date' -> throws 'Unknown unit date'; (d) an unsupported concept like dur.as('decade'). The alias getters (asMinutes, asSeconds, ...) call makeAs with a fixed valid alias so they never hit this path.","commonSituations":"Copying a unit string from a moment() date getter (e.g. .get('D') works for moments but 'D' -> 'date' throws for durations); reading the unit from a config/translation object whose key is missing (so the variable is undefined); passing a number or null by mistake; i18n maps where a translation key for the unit was never added; refactors that pass through user input without validating it.","solutions":["Pass a valid duration unit alias: one of ms/s/m/h/d/w/M/Q/y (or the full names milliseconds/seconds/minutes/hours/days/weeks/months/quarters/years).","If the unit comes from a variable, verify it is a defined string and one of the duration units before calling .as() (see validationCode / typeGuard).","If you actually need a calendar field (day-of-month, weekday, day-of-year, iso-week, week-year), use a moment object (e.g. moment().date(), moment().isoWeekday()) not a duration - durations only measure elapsed time in time/month units.","Default the unit with a known-good fallback when it is missing or unrecognized, instead of letting undefined reach .as()."],"exampleFix":"// before\nconst dur = moment.duration(90, 'minutes');\ndur.as('minut'); // throws: Unknown unit undefined\ndur.as('D');     // throws: Unknown unit date (calendar unit, not a duration unit)\ndur.as();       // throws: Unknown unit undefined\n\n// after\nconst dur = moment.duration(90, 'minutes');\ndur.as('minutes'); // 90\ndur.as('m');       // 90 (alias)\n// day-of-month is a calendar field - use a moment, not a duration:\nmoment().date();","handlingStrategy":"validation","validationCode":"// Mirror of the duration units as() actually accepts in src/lib/duration/as.js.\nconst DURATION_UNITS = new Set([\n    'ms', 'milliseconds', 'millisecond',\n    's', 'seconds', 'second',\n    'm', 'minutes', 'minute',\n    'h', 'hours', 'hour',\n    'd', 'days', 'day',\n    'w', 'weeks', 'week',\n    'M', 'months', 'month',\n    'Q', 'quarters', 'quarter',\n    'y', 'years', 'year',\n]);\n\n// normalizeUnits lowercases as a fallback (src/lib/units/aliases.js:56), so check both.\nfunction isValidDurationUnit(u) {\n    if (typeof u !== 'string') return false;\n    return DURATION_UNITS.has(u) || DURATION_UNITS.has(u.toLowerCase());\n}\n\n// usage - call BEFORE duration.as():\nconst unit = maybeUnitFromConfig;\nconst value = (unit != null && isValidDurationUnit(unit))\n    ? dur.as(unit)\n    : NaN; // or throw a clearer error with the offending value","typeGuard":"// TypeScript\ntype DurationUnit =\n    | 'ms' | 'milliseconds' | 'millisecond'\n    | 's' | 'seconds' | 'second'\n    | 'm' | 'minutes' | 'minute'\n    | 'h' | 'hours' | 'hour'\n    | 'd' | 'days' | 'day'\n    | 'w' | 'weeks' | 'week'\n    | 'M' | 'months' | 'month'\n    | 'Q' | 'quarters' | 'quarter'\n    | 'y' | 'years' | 'year';\n\nconst DURATION_UNITS: ReadonlySet<string> = new Set([\n    'ms', 'milliseconds', 'millisecond', 's', 'seconds', 'second',\n    'm', 'minutes', 'minute', 'h', 'hours', 'hour', 'd', 'days', 'day',\n    'w', 'weeks', 'week', 'M', 'months', 'month', 'Q', 'quarters',\n    'quarter', 'y', 'years', 'year',\n]);\n\nfunction isDurationUnit(u: unknown): u is DurationUnit {\n    return typeof u === 'string'\n        && (DURATION_UNITS.has(u) || DURATION_UNITS.has(u.toLowerCase()));\n}\n\n// narrows `unit` so dur.as(unit) is statically safe:\nif (isDurationUnit(unit)) {\n    return dur.as(unit);\n}","tryCatchPattern":"// Only if you genuinely can't validate up front. Narrow on the message so you don't swallow unrelated errors.\nlet value;\ntry {\n    value = dur.as(unit);\n} catch (e) {\n    if (e instanceof Error && /^Unknown unit/.test(e.message)) {\n        value = NaN; // or log + default\n    } else {\n        throw e;\n    }\n}","preventionTips":["Always pass the unit as a literal from a known set; never forward unvalidated user/config input straight into .as().","Remember durations have no calendar fields - no 'date', 'dayOfYear', 'weekday', 'isoWeek', 'weekYear'. Use a moment object for those.","When the unit comes from a config/i18n map, default it to a known-good unit when the key is missing rather than letting undefined propagate.","Enable TS strict mode and type the unit parameter as DurationUnit so typos and calendar units are rejected at compile time."],"tags":["moment","duration","units","validation","runtime"],"analyzedSha":"019806b26f544e42c42bcaafba0bfd3c9066c7db","analyzedAt":"2026-08-04T13:49:33.534Z","schemaVersion":2}