{"record":{"id":"d598a00b3c827612","repo":"octobercms/october","slug":"invalid-field-name-fieldname","errorCode":null,"errorMessage":"Invalid field name: {$fieldName}.","messagePattern":"Invalid field name: (.+?)\\.","errorType":"exception","errorClass":"BlueprintException","httpStatus":null,"severity":"error","filePath":"modules/tailor/classes/BlueprintVerifier.php","lineNumber":233,"sourceCode":"        $fields = $blueprint->fields ?? [];\n\n        if ($blueprint instanceof EntryBlueprint && is_array($blueprint->groups)) {\n            foreach ($blueprint->groups as $group) {\n                $fields += $group['fields'] ?? [];\n            }\n        }\n\n        // Validate source references from raw config (before fieldset expansion)\n        $this->validateSourceReferences($blueprint, $fields);\n\n        $fieldset = FieldManager::instance()->makeFieldset(['fields' => $fields]);\n        $fieldset->validate();\n\n        // Check invalid and reserved field names\n        foreach ($fieldset->getAllFields() as $fieldName => $fieldObj) {\n            if (!preg_match('/^[a-zA-Z0-9\\_]+$/', $fieldName)) {\n                $lineNo = $this->findLineFromKeyValPair($blueprint->content, $fieldName, '');\n                throw new BlueprintException($blueprint, \"Invalid field name: {$fieldName}.\", $lineNo);\n            }\n\n            if (in_array($fieldName, $this->reservedFieldNames)) {\n                $lineNo = $this->findLineFromKeyValPair($blueprint->content, $fieldName, '');\n                throw new BlueprintException($blueprint, \"Field name is reserved: {$fieldName}.\", $lineNo);\n            }\n        }\n    }\n\n    /**\n     * validateSourceReferences validates source references in raw field config recursively\n     */\n    protected function validateSourceReferences(Blueprint $blueprint, array $fields)\n    {\n        foreach ($fields as $fieldName => $fieldConfig) {\n            if (!is_array($fieldConfig)) {\n                continue;\n            }","sourceCodeStart":215,"sourceCodeEnd":251,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/tailor/classes/BlueprintVerifier.php#L215-L251","documentation":"The verifier iterates every field returned by the compiled fieldset (including fields pulled in via `import:` from shared fieldsets) and requires each field name to match /^[a-zA-Z0-9_]+$/. Any other character — dash, dot, space, unicode — makes the name unusable as a content column and model attribute, so validation fails naming the field.","triggerScenarios":"A blueprint or imported fieldset defines `my-field:`, `foo.bar:`, `items []:` or a quoted key containing a space. Because getAllFields() returns the expanded fieldset, the offending key may live in an imported fields/*.yaml file rather than the blueprint itself.","commonSituations":"Field names copy-pasted from HTML form markup (kebab-case); YAML keys with trailing spaces or tabs; non-ASCII/localised field names; a key accidentally parsed as a nested map (e.g. `foo: { }` style).","solutions":["Rename the field using only letters, numbers and underscores, e.g. `my_field:`.","If the error names a field you don't recognise in the blueprint, grep your theme's fieldset files (`fields/*.yaml`) — it was merged in via `import:`.","Check for invisible characters or trailing spaces around the YAML key; re-quote the key if needed."],"exampleFix":"# before\nfields:\n  my-field:\n    label: My Field\n    type: text\n\n# after\nfields:\n  my_field:\n    label: My Field\n    type: text","handlingStrategy":"validation","validationCode":"foreach ($fields as $name => $config) {\n    if (!preg_match('/^[a-zA-Z0-9_]+$/', (string) $name)) {\n        throw new InvalidArgumentException(\"Invalid field name: {$name}\");\n    }\n}","typeGuard":"function isValidTailorFieldName(string $name): bool\n{\n    return (bool) preg_match('/^[a-zA-Z0-9_]+$/', $name);\n}","tryCatchPattern":"try {\n    // blueprint scan / tailor:refresh\n} catch (\\Tailor\\Classes\\BlueprintException $e) {\n    // message contains the offending field name; grep blueprints AND imported fieldsets\n}","preventionTips":["Standardize on snake_case field names in all blueprint and fieldset YAML.","Lint field keys in CI with the same regex Tailor uses: /^[a-zA-Z0-9_]+$","When importing shared fieldsets, lint the imported files too — the verifier checks the expanded field list."],"tags":["tailor","field-name","yaml","validation"],"backgroundTag":"invalid-identifier","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}