{"id":"089fc8dec2e49418","repo":"laravel/framework","slug":"invoke-an-attribute-method-such-as-schedule-daily","errorCode":null,"errorMessage":"Invoke an attribute method such as Schedule::daily() before defining a schedule group.","messagePattern":"Invoke an attribute method such as Schedule::daily\\(\\) before defining a schedule group\\.","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Illuminate/Console/Scheduling/Schedule.php","lineNumber":334,"sourceCode":"        $this->events[] = $event = new Event($this->eventMutex, $command, $this->timezone);\n\n        $this->mergePendingAttributes($event);\n\n        return $event;\n    }\n\n    /**\n     * Create new schedule group.\n     *\n     * @param  \\Closure  $events\n     * @return void\n     *\n     * @throws \\RuntimeException\n     */\n    public function group(Closure $events)\n    {\n        if ($this->attributes === null) {\n            throw new RuntimeException('Invoke an attribute method such as Schedule::daily() before defining a schedule group.');\n        }\n\n        $this->groupStack[] = $this->attributes;\n        $this->attributes = null;\n\n        $events($this);\n\n        array_pop($this->groupStack);\n    }\n\n    /**\n     * Merge the current group attributes with the given event.\n     *\n     * @param  \\Illuminate\\Console\\Scheduling\\Event  $event\n     * @return void\n     */\n    protected function mergePendingAttributes(Event $event)\n    {","sourceCodeStart":316,"sourceCodeEnd":352,"githubUrl":"https://github.com/laravel/framework/blob/bd6b5437e6ad87bb49f9b426724f07a9f64e9683/src/Illuminate/Console/Scheduling/Schedule.php#L316-L352","documentation":"Thrown by Schedule::group() (src/Illuminate/Console/Scheduling/Schedule.php:334) when $this->attributes is null — i.e. group() was called before any attribute method (daily(), hourly(), runInBackground(), etc.) populated pending attributes. Groups apply shared attributes to every event inside, so they must be set first.","triggerScenarios":"Writing $schedule->group(function ($schedule) { $schedule->call(...); }); with no prior attribute call like $schedule->daily()->group(...).","commonSituations":"Adopting the fluent Schedule builder API and forgetting the attribute chain; refactoring that drops the attribute call before group.","solutions":["Chain an attribute method before group(): $schedule->daily()->group(fn ($s) => ...).","Move shared constraints (timezone, environments) inside the group via attribute calls on $s.","If no shared attributes are needed, don't use group() — register events directly."],"exampleFix":"// before\n$schedule->group(function ($schedule) {\n    $schedule->call(fn () => x())->daily();\n    $schedule->command('reports:send')->daily();\n});\n\n// after\n$schedule->daily()->group(function ($schedule) {\n    $schedule->call(fn () => x());\n    $schedule->command('reports:send');\n});","handlingStrategy":"validation","validationCode":"// group() requires attributes set first; ensure an attribute method runs first\n$schedule->daily()->group(fn ($s) => /* events */);","typeGuard":"// internal-only: attributes populated by an attribute call\n// users guard by always chaining an attribute before group()","tryCatchPattern":"try {\n    $schedule->group($closure);\n} catch (\\RuntimeException $e) {\n    $schedule->daily()->group($closure); // retry with attribute\n}","preventionTips":["Always chain a frequency/attribute method before group().","Skip group() when no shared attributes are needed.","Add a lint rule banning bare group() calls."],"tags":["scheduling","console","api-misuse","laravel"],"analyzedSha":"bd6b5437e6ad87bb49f9b426724f07a9f64e9683","analyzedAt":"2026-08-06T00:28:32.783Z","schemaVersion":2}