{"record":{"id":"2e00d27ddf3a42a1","repo":"octobercms/october","slug":"repeater-must-specify-either-a-form-or-group-p","errorCode":null,"errorMessage":"Repeater must specify either a \"form\" or \"group\" property for the form fields","messagePattern":"Repeater must specify either a \"form\" or \"group\" property for the form fields","errorType":"exception","errorClass":"SystemException","httpStatus":null,"severity":"error","filePath":"modules/tailor/contentfields/RepeaterField.php","lineNumber":50,"sourceCode":"    {\n        if (isset($config['form'])) {\n            $this->fieldsetConfig = (array) $config['form'];\n            $this->useGroups = false;\n        }\n\n        if (isset($config['groups'])) {\n            $this->fieldsetConfig = (array) $config['groups'];\n            $this->useGroups = true;\n        }\n    }\n\n    /**\n     * validateConfig\n     */\n    public function validateConfig()\n    {\n        if ($this->fieldsetConfig === null) {\n            throw new SystemException('Repeater must specify either a \"form\" or \"group\" property for the form fields');\n        }\n    }\n\n    /**\n     * defineFormField will define how a field is displayed in a form.\n     */\n    public function defineFormField(FormElement $form, $context = null)\n    {\n        $config = ['groupKeyFrom' => 'content_group'] + $this->getCleanFormConfig();\n\n        $form->addFormField($this->fieldName, $this->label)->useConfig($config);\n    }\n\n    /**\n     * defineBatchListColumn\n     */\n    public function defineBatchListColumn(ListElement $list, $context = null)\n    {","sourceCodeStart":32,"sourceCodeEnd":68,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/tailor/contentfields/RepeaterField.php#L32-L68","documentation":"Thrown by Tailor's Repeater content field during validateConfig() when neither a form nor groups property was supplied in the field configuration. A repeater field needs a fieldset to render its repeated items; if fieldsetConfig is still null after defineConfig() processes the config, the field is invalid and a SystemException is raised.","triggerScenarios":"Declaring a repeater content field in a blueprint without a form: or groups: key, or misspelling those keys (e.g. field: instead of form:, group: instead of groups:). The exception fires when the fieldset is validated, which happens while Tailor compiles the blueprint's form definition.","commonSituations":"Copy-pasting a widget config that used different key names; YAML indentation mistakes that put form: under the wrong level so it is not seen; renaming keys when migrating from the backend form widget syntax to Tailor blueprint syntax.","solutions":["Add a form: key with the repeated fields (single group) or a groups: key with named group definitions to the repeater field in your blueprint","Check YAML indentation: form/groups must sit directly under the repeater field name, one level deeper than fields:","Remove the repeater field entirely if it was added as a placeholder with no configuration"],"exampleFix":"# before\nfields:\n  slides:\n    type: repeater\n    # no form or groups key\n\n# after\nfields:\n  slides:\n    type: repeater\n    form:\n      fields:\n        title:\n          type: text\n        image:\n          type: mediafinder","handlingStrategy":"validation","validationCode":"// Validate repeater field config before saving/compiling a blueprint\n$repeaterConfig = $fieldset['fields']['slides'] ?? null;\nif (($repeaterConfig['type'] ?? '') === 'repeater'\n    && !isset($repeaterConfig['form'], $repeaterConfig['groups'])) {\n    throw new InvalidArgumentException(\"Repeater field [slides] must define 'form' or 'groups'\");\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Lint blueprint YAML in CI: every field with type: repeater must carry a form: or groups: key","Copy repeater field examples from the official Tailor docs rather than the backend form widget syntax","Watch YAML indentation — form/groups nested one level too deep are silently ignored"],"tags":["tailor","octobercms","repeater","blueprint","configuration","validation"],"backgroundTag":"missing-required-config-key","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}