{"record":{"id":"e90e562f08f0702b","repo":"briannesbitt/Carbon","slug":"unsupported-unit-unit","errorCode":null,"errorMessage":"Unsupported unit '$unit'","messagePattern":"Unsupported unit '\\$unit'","errorType":"exception","errorClass":"UnsupportedUnitException","httpStatus":null,"severity":"error","filePath":"src/Carbon/Traits/Units.php","lineNumber":569,"sourceCode":"            'minus' => $this->doMinus(...$parameters),\n            default => null,\n        };\n    }\n\n    private static function rawAddUnit(self $date, string $unit, int|float $value): ?static\n    {\n        try {\n            $absoluteValue = abs($value);\n\n            return $date->rawAdd(\n                CarbonInterval::fromString(self::getNumberAsString($absoluteValue).\" $unit\")\n                    ->invert($value < 0),\n            );\n        } catch (InvalidIntervalException $exception) {\n            try {\n                return $date->modify(self::getNumberAsString($value).\" $unit\");\n            } catch (InvalidFormatException) {\n                throw new UnsupportedUnitException($unit, previous: $exception);\n            }\n        }\n    }\n\n    private static function getNumberAsString(int|float $value): string\n    {\n        $stringValue = (string) $value;\n\n        if ($value < -1 || $value > 1) {\n            if (str_contains($stringValue, 'E')) {\n                return number_format($value, 0, '.', '');\n            }\n\n            return $stringValue;\n        }\n\n        if (str_contains($stringValue, 'E')) {\n            return number_format($value, 14, '.', '');","sourceCodeStart":551,"sourceCodeEnd":587,"githubUrl":"https://github.com/briannesbitt/Carbon/blob/b13f05955dcfd7da71d60af745fd148cbdb73505/src/Carbon/Traits/Units.php#L551-L587","documentation":"Inside rawAddUnit(), Carbon first builds CarbonInterval::fromString(\"<number> <unit>\"); if that throws InvalidIntervalException it retries with DateTime::modify(\"<number> <unit>\"). When both parsers reject the unit, UnsupportedUnitException is thrown with the unit name and the interval-parse failure chained as previous. This is the low-level 'this unit name means nothing to Carbon or PHP relative formats' signal; addUnit() normally wraps it into a broader UnitException.","triggerScenarios":"A unit only your domain understands ('businessDay', 'sprint', 'fortnight', 'payPeriod') reaching rawAddUnit; concatenated strings like 'sec'.'onds' producing 'sec onds'; calling CarbonInterval-unsupported unit through any add/sub path; empty unit resulting in a bare '3 ' string both parsers reject.","commonSituations":"Domain-specific duration vocabularies passed to generic helpers; renaming unit constants and missing call sites; code that assumed strtotime-compatible words ('fortnight' is not a PHP relative unit); data from spreadsheets/APIs with free-text units.","solutions":["Map the domain unit to a real Carbon unit before calling (businessDay -> weekday + skip logic, sprint -> N days)","Use CarbonInterval::fromString() on the raw text first to validate vocabulary cheaply and early","Catch UnsupportedUnitException specifically when you need to distinguish 'bad unit' from other addUnit failures (it will otherwise be re-wrapped in UnitException by addUnit)","Replace free-text units with the Unit enum at your input boundary"],"exampleFix":"// before\n$date->addUnit($plan->cycle_unit, 1); // 'fortnight' -> UnsupportedUnitException\n\n// after\n$map = ['fortnight' => ['day', 14], 'businessDay' => ['weekday', 1]];\n[$unit, $factor] = $map[$plan->cycle_unit] ?? [$plan->cycle_unit, 1];\n$date->addUnit($unit, $factor);","handlingStrategy":"type-guard","validationCode":"try {\n    CarbonInterval::fromString('1 '.strtolower((string) $unit)); // dry-run the vocabulary\n} catch (InvalidIntervalException $e) {\n    throw new InvalidArgumentException(\"Unit '$unit' is not understood\");\n}\n// DateTime-relative fallbacks ('weekday' etc.) may still pass - keep the try/catch too","typeGuard":"function isSupportedIntervalUnit(string $unit): bool\n{\n    try {\n        CarbonInterval::fromString('1 '.strtolower($unit));\n\n        return true;\n    } catch (InvalidIntervalException) {\n        return false;\n    }\n}","tryCatchPattern":"use Carbon\\Exceptions\\UnsupportedUnitException;\nuse Carbon\\Exceptions\\UnitException;\n\ntry {\n    $date = $date->addUnit($unit, $value);\n} catch (UnitException $e) {\n    if ($e->getPrevious() instanceof UnsupportedUnitException) {\n        [$unit, $value] = translateDomainUnit($unit, $value); // e.g. fortnight -> 14 days\n        $date = $date->addUnit($unit, $value);\n    } else {\n        throw $e;\n    }\n}","preventionTips":["Map domain vocabulary (business day, sprint) to Carbon units at the edge, not inside arithmetic","Accept the Unit enum in your own APIs so invalid strings cannot travel","Remember addUnit re-wraps UnsupportedUnitException into UnitException - check the previous exception"],"tags":["php","carbon","unit-validation","date-arithmetic","invalid-argument"],"backgroundTag":"invalid-time-unit","analyzedSha":"b13f05955dcfd7da71d60af745fd148cbdb73505","analyzedAt":"2026-08-17T04:40:56.953Z","schemaVersion":2},"datasetVersion":"2026-08-17T09:17:11.063Z"}