octobercms/october · error · SystemException

Import class '{$className}' does not exist.

Error message

Import class '{$className}' does not exist.

What it means

After the schema checks pass, processSeedInstruction() instantiates the importer - but only after verifying class_exists($className). A non-loadable class name in seeds/data.yaml (wrong namespace, typo, plugin not installed, autoloader not aware) aborts seeding with this SystemException naming the class.

Source

Thrown at modules/cms/models/ThemeSeed.php:224

    {
        $importName = $instruction['name'] ?? 'Import Data';
        $className = $instruction['class'] ?? null;
        $fileName = $instruction['file'] ?? null;
        $attributes = $instruction['attributes'] ?? null;
        $matches = $instruction['matches'] ?? null;

        if (!$className) {
            throw new SystemException("Import script is missing definition for 'class'");
        }
        if (!$fileName) {
            throw new SystemException("Import script is missing definition for 'file'");
        }
        if (!$attributes || !is_array($attributes)) {
            throw new SystemException("Import script is missing definition for 'attributes'");
        }

        if (!class_exists($className)) {
            throw new SystemException("Import class '{$className}' does not exist.");
        }

        $importFile = $this->themePath . '/' . $fileName;
        if (!File::exists($importFile)) {
            throw new SystemException("Import file '{$fileName}' does not exist.");
        }

        $importModel = new $className;
        $importModel->forceFill($attributes);

        if (method_exists($importModel, 'setSourcePrefix')) {
            $importModel->setSourcePrefix($this->themePath);
        }

        $importModel->importFile($importFile, ['matches' => $matches, 'sessionKey' => str_random(40)]);

        $stats = $importModel->getResultStats();
        $this->note("- <info>{$importName}</info>: {$stats->created} Created / {$stats->updated} Updated / {$stats->skippedCount} Skipped");

View on GitHub (pinned to b608633a7e)

Solutions

  1. Check the exact value: php artisan tinker, then class_exists('Acme\Blog\Classes\PostImport'); - fix namespace/typo until true.
  2. Ensure the plugin providing the class is installed and enabled (backend System > Updates, or plugin:install).
  3. In double-quoted YAML, escape backslashes ('Acme\\Blog\\...') or use single-quoted scalars.
  4. Run composer dump-autoload if the class was just added.

Example fix

# before - double-quoted YAML ate the backslashes -> class not loadable
class: "Acme\Blog\Classes\PostImport"

# after - single-quoted scalar keeps namespaces intact
class: 'Acme\Blog\Classes\PostImport'
Defensive patterns

Strategy: validation

Validate before calling

foreach ((array) Yaml::parseFile($themePath . '/seeds/data.yaml') as $i => $ins) {
    if (!empty($ins['class']) && !class_exists($ins['class'])) {
        $errors[] = "instruction {$i}: class {$ins['class']} not loadable";
    }
}

Type guard

function seedClassLoadable(string $class): bool
{
    return class_exists($class);
}

Try / catch

try {
    \Artisan::call('theme:seed', ['name' => $themeDir]);
} catch (\October\Rain\Exception\SystemException $e) {
    // check class_exists() in tinker; fix namespace/escaping or install the plugin
}

Prevention

When it happens

Trigger: theme:seed on a theme whose data.yaml references a class the app cannot autoload: namespace typo (Acme\Blog\Clases\PostImport), plugin not installed/disabled, YAML double-quoted string where backslashes were mis-escaped, or a newly added class without a fresh composer dump-autoload.

Common situations: Shipping a theme that seeds another plugin's models without declaring that plugin as a requirement; moving classes during refactoring without updating seed files; YAML escaping confusion between single and double quotes.

Related errors


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