octobercms/october · error · BlueprintException
Field name is reserved: {$fieldName}.
Error message
Field name is reserved: {$fieldName}. What it means
Tailor reserves certain field names because they collide with columns, attributes and relations that generated content models always define — `attributes`, `site_id`, `site_root_id`, `created_user_id`, `relation_id`, `field_name`, `nest_left`, `nest_right`, `blueprint_uuid`, `primary_id`, `content_group`, `primaryRecord`, and more. The verifier rejects any field on that list (mirrored in SchemaBuilder::$reservedFieldNames), including fields arriving through imported fieldsets.
Source
Thrown at modules/tailor/classes/BlueprintVerifier.php:238
}
}
// Validate source references from raw config (before fieldset expansion)
$this->validateSourceReferences($blueprint, $fields);
$fieldset = FieldManager::instance()->makeFieldset(['fields' => $fields]);
$fieldset->validate();
// Check invalid and reserved field names
foreach ($fieldset->getAllFields() as $fieldName => $fieldObj) {
if (!preg_match('/^[a-zA-Z0-9\_]+$/', $fieldName)) {
$lineNo = $this->findLineFromKeyValPair($blueprint->content, $fieldName, '');
throw new BlueprintException($blueprint, "Invalid field name: {$fieldName}.", $lineNo);
}
if (in_array($fieldName, $this->reservedFieldNames)) {
$lineNo = $this->findLineFromKeyValPair($blueprint->content, $fieldName, '');
throw new BlueprintException($blueprint, "Field name is reserved: {$fieldName}.", $lineNo);
}
}
}
/**
* validateSourceReferences validates source references in raw field config recursively
*/
protected function validateSourceReferences(Blueprint $blueprint, array $fields)
{
foreach ($fields as $fieldName => $fieldConfig) {
if (!is_array($fieldConfig)) {
continue;
}
// Check source at this level
$source = $fieldConfig['source'] ?? null;
if ($source && !$this->sourceExists($source)) {
$lineNo = $this->findLineFromKeyValPair($blueprint->content, 'source', $source);View on GitHub (pinned to b608633a7e)
Solutions
- Rename the field to a non-reserved name, e.g. `site` instead of `site_id`.
- Check the full reserved list in Tailor\Classes\BlueprintVerifier::{$reservedFieldNames} (duplicated in Tailor\Classes\SchemaBuilder) and avoid every entry.
- If the field comes from an imported fieldset, fix it in that fieldset file — the verifier checks the expanded field list.
Example fix
# before
fields:
attributes:
label: Attributes
type: text
# after
fields:
product_attributes:
label: Attributes
type: text Defensive patterns
Strategy: validation
Validate before calling
$reserved = (new \ReflectionClass(\Tailor\Classes\BlueprintVerifier::class))
->getDefaultProperties()['reservedFieldNames'];
foreach ($fields as $name => $config) {
if (in_array($name, $reserved)) {
throw new InvalidArgumentException("Reserved field name: {$name}");
}
} Type guard
function isReservedTailorFieldName(string $name): bool
{
static $reserved;
$reserved = $reserved ?? (new \ReflectionClass(\Tailor\Classes\BlueprintVerifier::class))
->getDefaultProperties()['reservedFieldNames'];
return in_array($name, $reserved, true);
} Try / catch
try {
// blueprint scan
} catch (\Tailor\Classes\BlueprintException $e) {
// message names the reserved field; rename it in the blueprint or imported fieldset
} Prevention
- Keep a checklist of reserved names (read from the BlueprintVerifier reservedFieldNames property) during content modeling reviews.
- Avoid naming fields after database-sounding concepts (site_id, relation_id, nest_left, attributes).
- Re-run tailor:refresh after October upgrades — new reserved names may have been added.
When it happens
Trigger: A blueprint field is named exactly `attributes`, `site_id`, `content_group`, `primaryRecord`, or another reserved entry; or a shared fieldset imported with `import:` contains one of those names and gets expanded by getAllFields().
Common situations: Naming a field after internal columns (e.g. `site_id` for a site picker, `attributes` for a generic fieldset); fieldsets written before a name became reserved in a newer October build; content_group used for navigation grouping.
Related errors
- Type must be one of: {$typeAsString}.
- Invalid source reference '{$source}'. No blueprint found wit
- Repeater must specify either a "form" or "group" property fo
- Invalid field name: {$fieldName}.
- Blueprint not found
AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21).
Data as JSON: /api/errors/12f92a9cdc49c475.
Report an issue: GitHub.