octobercms/october · error · BlueprintException

Type must be one of: {$typeAsString}.

Error message

Type must be one of: {$typeAsString}.

What it means

Thrown by Tailor's BlueprintVerifier while scanning blueprint YAML files: the blueprint's top-level `type:` value is not one of the six supported types (entry, stream, structure, single, mixin, global). Tailor uses the type to decide which model, table and behaviours to generate, so an unknown value aborts validation, with the offending line located via findLineFromKeyValPair.

Source

Thrown at modules/tailor/classes/BlueprintVerifier.php:162

            $this->yamlToBlueprintException($blueprint, $ex);
        }
    }

    /**
     * validateSupportedTypes checks for valid blueprint types
     */
    protected function validateSupportedTypes(Blueprint $blueprint)
    {
        $supportedTypes = ['entry', 'stream', 'structure', 'single', 'mixin', 'global'];

        if (in_array($blueprint->type, $supportedTypes)) {
            return;
        }

        $lineNo = $this->findLineFromKeyValPair($blueprint->content, 'type', $blueprint->type);

        $typeAsString = implode(', ', $supportedTypes);
        throw new BlueprintException($blueprint, "Type must be one of: {$typeAsString}.", $lineNo);
    }

    /**
     * validateUniqueBlueprint checks for duplicate handles and UUIDs across blueprints
     */
    protected function validateUniqueBlueprint(Blueprint $blueprint)
    {
        $filePath = $blueprint->getFilePath();
        $theme = $blueprint->getDatasourceTheme();

        // Check handle uniqueness (all blueprints share the same namespace)
        if ($handle = $blueprint->handle) {
            $this->validateUniqueProperty($blueprint, 'handle', $handle, $filePath, $theme);
        }

        // Check UUID uniqueness
        if ($uuid = $blueprint->uuid) {
            $this->validateUniqueProperty($blueprint, 'uuid', $uuid, $filePath, $theme);

View on GitHub (pinned to b608633a7e)

Solutions

  1. Set `type:` to one of: entry, stream, structure, single, mixin, global (e.g. `type: entry`).
  2. Check YAML indentation — `type` must be a top-level key of the blueprint file, not nested under another key.
  3. Re-run `php artisan tailor:refresh` after fixing to confirm the blueprint passes validation.

Example fix

# before (themes/mytheme/blueprints/blog.yaml)
type: entries

# after
type: entry
Defensive patterns

Strategy: validation

Validate before calling

$supported = ['entry', 'stream', 'structure', 'single', 'mixin', 'global'];
$content = \Symfony\Component\Yaml\Yaml::parseFile($blueprintPath);
$type = $content['type'] ?? null;
if (!in_array($type, $supported, true)) {
    throw new InvalidArgumentException("{$blueprintPath}: unsupported blueprint type " . var_export($type, true));
}

Type guard

function isSupportedBlueprintType($type): bool
{
    return in_array($type, ['entry', 'stream', 'structure', 'single', 'mixin', 'global'], true);
}

Try / catch

try {
    // tailor:refresh / blueprint scan
} catch (\Tailor\Classes\BlueprintException $e) {
    // $e->getMessage() names the type and file; fix YAML and rescan
}

Prevention

When it happens

Trigger: A blueprint file in themes/<theme>/blueprints/ contains e.g. `type: blog` or `type: entries` (plural) instead of `entry`. Validation runs when Tailor scans blueprints (opening the Tailor backend section, `php artisan tailor:refresh`, cache clear), so the exception surfaces at scan time.

Common situations: Typos in the type key; YAML indentation nesting `type` under another key so it parses as null or an unexpected value; blueprints copied from plugins or docs expecting a custom type; type names changed between October versions.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of octobercms/october@b608633a7e (2026-08-21). Data as JSON: /api/errors/19aeb673a4fe6e49. Report an issue: GitHub.