{"record":{"id":"4950f5e18d199b6e","repo":"flarum/framework","slug":"last-update-runs-can-only-be-for-one-of-minor-major-global","errorCode":null,"errorMessage":"Last update runs can only be for one of: minor, major, global","messagePattern":"Last update runs can only be for one of: minor, major, global","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"extensions/package-manager/src/Settings/LastUpdateRun.php","lineNumber":32,"sourceCode":"use Flarum\\Settings\\SettingsRepositoryInterface;\n\nclass LastUpdateRun implements JsonSetting\n{\n    public const SUCCESS = 'success';\n    public const FAILURE = 'failure';\n    protected array $data;\n    protected ?string $activeUpdate;\n\n    public function __construct(\n        protected SettingsRepositoryInterface $settings,\n    ) {\n        $this->data = self::default();\n    }\n\n    public function for(string $update): self\n    {\n        if (! in_array($update, [FlarumUpdated::MAJOR, FlarumUpdated::MINOR, FlarumUpdated::GLOBAL])) {\n            throw new \\InvalidArgumentException('Last update runs can only be for one of: minor, major, global');\n        }\n\n        $this->activeUpdate = $update;\n\n        return $this;\n    }\n\n    public function with(string $key, mixed $value): JsonSetting\n    {\n        $this->data[$this->activeUpdate][$key] = $value;\n\n        return $this;\n    }\n\n    public function save(): array\n    {\n        $this->data[$this->activeUpdate]['ranAt'] = Carbon::now();\n","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/flarum/framework/blob/4b939f685389bfe8a380e9e28ddf305a1c66950c/extensions/package-manager/src/Settings/LastUpdateRun.php#L14-L50","documentation":"LastUpdateRun::for() restricts its argument to the three FlarumUpdated constants: MAJOR, MINOR and GLOBAL. Any other string is rejected with an InvalidArgumentException before being stored as the active update type. This prevents recording update-run state for unknown update categories.","triggerScenarios":"Calling LastUpdateRun::for() with a literal string such as 'patch', 'security', 'Major' (wrong case), or a translated/custom label instead of exactly FlarumUpdated::MAJOR ('major'), ::MINOR ('minor') or ::GLOBAL ('global').","commonSituations":"Hard-coding the update kind in extension code instead of importing the FlarumUpdated constants; case mismatch when the value comes from user input or a config file; passing an update type added in a newer Flarum version that this Settings class doesn't whitelist.","solutions":["Pass one of FlarumUpdated::MAJOR, FlarumUpdated::MINOR or FlarumUpdated::GLOBAL instead of a raw string.","Validate/normalize the incoming update kind (strtolower + whitelist check) before calling for().","If you need a new update category, extend the allowed list in FlarumUpdated and in this check rather than passing an ad-hoc string."],"exampleFix":"// before\n$lastUpdateRun->for($input['update_type']);\n// after\n$kind = strtolower(trim($input['update_type']));\nif (! in_array($kind, [FlarumUpdated::MAJOR, FlarumUpdated::MINOR, FlarumUpdated::GLOBAL], true)) {\n    throw new \\InvalidArgumentException('Unsupported update type');\n}\n$lastUpdateRun->for($kind);","handlingStrategy":"validation","validationCode":"$allowed = [FlarumUpdated::MAJOR, FlarumUpdated::MINOR, FlarumUpdated::GLOBAL];\nif (! in_array($update, $allowed, true)) {\n    throw new \\InvalidArgumentException('Update type must be one of: ' . implode(', ', $allowed));\n}","typeGuard":"function isValidUpdateType(string $v): bool {\n    return in_array($v, [FlarumUpdated::MAJOR, FlarumUpdated::MINOR, FlarumUpdated::GLOBAL], true);\n}","tryCatchPattern":"try {\n    $lastUpdateRun->for($update);\n} catch (\\InvalidArgumentException $e) {\n    // normalize or log invalid update type\n    $update = strtolower($update);\n}","preventionTips":["Always use the FlarumUpdated class constants, never string literals.","Normalize user/config-provided values with strtolower before passing.","Whitelist-validate external input mapping to update kinds."],"tags":["invalid-argument","enum","package-manager","settings"],"backgroundTag":"invalid-enum-value","analyzedSha":"4b939f685389bfe8a380e9e28ddf305a1c66950c","analyzedAt":"2026-09-15T18:09:20.879Z","contentChangedAt":"2026-09-15T18:09:20.879Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}