{"record":{"id":"e62e485e851b0dbd","repo":"briannesbitt/Carbon","slug":"unknown-unit-unit-e62e48","errorCode":null,"errorMessage":"Unknown unit '$unit'.","messagePattern":"Unknown unit '\\$unit'\\.","errorType":"exception","errorClass":"UnknownUnitException","httpStatus":null,"severity":"error","filePath":"src/Carbon/Traits/Rounding.php","lineNumber":74,"sourceCode":"        $ranges = array_merge(static::getRangesByUnit($this->daysInMonth), [\n            // @call roundUnit\n            'microsecond' => [0, 999999],\n        ]);\n        $factor = 1;\n\n        if ($normalizedUnit === 'week') {\n            $normalizedUnit = 'day';\n            $precision *= static::DAYS_PER_WEEK;\n        }\n\n        if (isset($metaUnits[$normalizedUnit])) {\n            [$factor, $normalizedUnit] = $metaUnits[$normalizedUnit];\n        }\n\n        $precision *= $factor;\n\n        if (!isset($ranges[$normalizedUnit])) {\n            throw new UnknownUnitException($unit);\n        }\n\n        $found = false;\n        $fraction = 0;\n        $arguments = null;\n        $initialValue = null;\n        $factor = $this->year < 0 ? -1 : 1;\n        $changes = [];\n        $minimumInc = null;\n\n        foreach ($ranges as $unit => [$minimum, $maximum]) {\n            if ($normalizedUnit === $unit) {\n                $arguments = [$this->$unit, $minimum];\n                $initialValue = $this->$unit;\n                $fraction = $precision - floor($precision);\n                $found = true;\n\n                continue;","sourceCodeStart":56,"sourceCodeEnd":92,"githubUrl":"https://github.com/briannesbitt/Carbon/blob/b13f05955dcfd7da71d60af745fd148cbdb73505/src/Carbon/Traits/Rounding.php#L56-L92","documentation":"Thrown by roundUnit()/ceilUnit()/floorUnit() (and the round()/ceil()/floor() wrappers that take a unit) when the requested unit is not in the rounding ranges table. The unit is first singularized and meta-units are normalized (millennium/century/decade to year, quarter to month, millisecond to microsecond, week to day with precision x 7); anything left over - a typo or a non-temporal word - has no range to iterate, so Carbon rejects it with UnknownUnitException. It exists to fail fast instead of silently returning an unrounded date.","triggerScenarios":"Calling Carbon::parse('2024-01-15 10:23')->roundUnit('miutes') (typo); ->roundUnit('fortnight'); ->floorUnit('') with an empty string; ->ceilUnit('timezone') with a property name instead of a unit; passing a unit string taken straight from an HTTP request, config value, or DB column without whitelisting it.","commonSituations":"Unit names assembled dynamically from user input or i18n config; renaming a unit in one place ('mins') while roundUnit expects 'minute'; copying a unit that works with diffForHumans or CarbonInterval (e.g. a plural or an alias) into a rounding call where it is not supported; upgrading Carbon major versions where accepted alias lists changed.","solutions":["Fix the unit string to a supported one: millennium, century, decade, quarter, year, month, week, day, hour, minute, second, millisecond, microsecond (singular; some plurals are normalized via singularUnit, but verify with the exact string you pass)","Whitelist the unit against that list before calling roundUnit/ceilUnit/floorUnit when the value comes from external input","Wrap the call in try/catch (UnknownUnitException) and fall back to a known-safe unit such as 'day' or reject the request","Check the exception message: it echoes the original $unit before normalization, so the typo is visible verbatim"],"exampleFix":"// before\n$date->roundUnit($request->query('unit'));\n\n// after\n$allowed = ['millennium','century','decade','quarter','year','month','week','day','hour','minute','second','millisecond','microsecond'];\n$unit = strtolower((string) $request->query('unit'));\n$date->roundUnit(in_array($unit, $allowed, true) ? $unit : 'day');","handlingStrategy":"type-guard","validationCode":"$unit = Carbon::singularUnit(strtolower((string) $inputUnit));\nif (!in_array($unit, ['millennium','century','decade','quarter','year','month','week','day','hour','minute','second','millisecond','microsecond'], true)) {\n    throw new InvalidArgumentException(\"Unsupported rounding unit: $inputUnit\");\n}\n$date->roundUnit($unit, $precision);","typeGuard":"function isRoundableUnit(string $unit): bool\n{\n    return in_array(Carbon::singularUnit(strtolower($unit)), [\n        'millennium','century','decade','quarter','year','month','week','day',\n        'hour','minute','second','millisecond','microsecond',\n    ], true);\n}","tryCatchPattern":"use Carbon\\Exceptions\\UnknownUnitException;\n\ntry {\n    $date = $date->roundUnit($unit);\n} catch (UnknownUnitException $e) {\n    $date = $date->roundUnit('day'); // or reject the input with 422\n}","preventionTips":["Keep the unit list in one shared constant/enum and reuse it in both validation and rounding calls","Never forward raw request/config strings into roundUnit without a whitelist","Normalize with Carbon::singularUnit() before comparing so plurals never sneak through as 'valid'"],"tags":["php","carbon","rounding","unit-validation","invalid-argument"],"backgroundTag":"invalid-time-unit","analyzedSha":"b13f05955dcfd7da71d60af745fd148cbdb73505","analyzedAt":"2026-08-17T04:40:56.953Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}