{"record":{"id":"5458273e9de70870","repo":"coollabsio/coolify","slug":"invalid-cron-human-expression","errorCode":null,"errorMessage":"Invalid Cron / Human expression","messagePattern":"Invalid Cron / Human expression","errorType":"validation","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"app/Livewire/Project/Database/BackupEdit.php","lineNumber":341,"sourceCode":"        // S3 backup cannot be enabled without a valid S3 storage owned by the team\n        $availableS3Ids = $this->availableS3StorageIds();\n        if ($availableS3Ids->isEmpty()) {\n            $this->backup->s3_storage_id = $this->s3StorageId = null;\n            if ($this->backup->save_s3) {\n                $this->backup->save_s3 = $this->saveS3 = false;\n            }\n        } elseif (! $availableS3Ids->contains($this->backup->s3_storage_id)) {\n            $this->backup->s3_storage_id = $this->s3StorageId = $availableS3Ids->first();\n        }\n\n        // Validate that disable_local_backup can only be true when S3 backup is enabled\n        if ($this->backup->disable_local_backup && ! $this->backup->save_s3) {\n            $this->backup->disable_local_backup = $this->disableLocalBackup = false;\n        }\n\n        $isValid = validate_cron_expression($this->backup->frequency);\n        if (! $isValid) {\n            throw new Exception('Invalid Cron / Human expression');\n        }\n        $this->validate();\n    }\n\n    private function availableS3StorageIds(): Collection\n    {\n        $storages = collect($this->availableS3Storages);\n        $storageIds = $storages->pluck('id')->filter()->all();\n\n        if (empty($storageIds)) {\n            return collect();\n        }\n\n        $teamIds = $storages->pluck('team_id')->reject(fn ($teamId) => $teamId === null)->unique()->values()->all();\n\n        if (empty($teamIds)) {\n            return collect();\n        }","sourceCodeStart":323,"sourceCodeEnd":359,"githubUrl":"https://github.com/coollabsio/coolify/blob/70b9acc42467278373e00de77abb40684e25b395/app/Livewire/Project/Database/BackupEdit.php#L323-L359","documentation":"The BackupEdit Livewire component validates backup->frequency with validate_cron_expression() before saving. That helper accepts a 5-field cron expression that dragonmantank/cron's CronExpression::isValid() approves, or one of Coolify's built-in human presets (keys of VALID_CRON_STRINGS). Anything else — empty value, typo'd preset, or malformed cron — throws this generic Exception from the component's update flow.","triggerScenarios":"Saving a scheduled database backup with a frequency that is neither valid 5-field cron nor a supported preset string; the field left empty by a form reset; pasting a 6-field (with seconds) or 7-field cron from another system; stray whitespace/newlines in the input.","commonSituations":"Typing free text instead of picking the UI dropdown preset; using '@fortnightly' or other expressions the cron library rejects; old backup rows whose frequency a cron-library upgrade now refuses to validate.","solutions":["Set frequency to a standard 5-field cron expression, e.g. '0 2 * * *' for 02:00 daily.","Or pick one of Coolify's presets from the dropdown (keys of VALID_CRON_STRINGS in bootstrap/helpers, e.g. every_minute / every_hour).","Trim accidental whitespace and make sure the field is not empty before submitting.","If an existing backup suddenly fails after an upgrade, re-select its schedule from the UI dropdown and save again."],"exampleFix":"// before\n$backup->frequency = '@fortnightly';\n\n// after: plain 5-field cron, Mondays 03:00\n$backup->frequency = '0 3 * * 1';","handlingStrategy":"validation","validationCode":"// Validate before persisting any backup frequency\nif (! validate_cron_expression(trim($frequency))) {\n    return back()->withErrors(['frequency' => 'Invalid cron or preset expression']);\n}","typeGuard":null,"tryCatchPattern":"In Livewire: try { $this->validateFrequency(); } catch (Exception $e) { $this->addError('backup.frequency', 'Use a 5-field cron expression or a preset from the dropdown.'); }","preventionTips":["Offer the preset dropdown in UIs instead of free text where possible.","Trim whitespace and reject empty strings before validate_cron_expression (it returns false for empty).","After cron-library upgrades, smoke-test stored frequencies."],"tags":["cron","backup","validation","livewire","coolify"],"backgroundTag":"invalid-cron-expression","analyzedSha":"70b9acc42467278373e00de77abb40684e25b395","analyzedAt":"2026-08-17T01:41:01.313Z","schemaVersion":2},"datasetVersion":"2026-08-17T04:17:16.089Z"}