octobercms/october · error · SystemException

cms::lang.theme.edit.not_set

Error message

cms::lang.theme.edit.not_set

What it means

Thrown by Theme::getEditTheme() when Winter CMS cannot determine which theme the backend editor should operate on. The edit theme is resolved in order: the backend user's stored preference, the cms.edit_theme config value, then the active theme code. If all three are empty the exception fires, which almost always means the installation has no active theme configured at all.

Source

Thrown at modules/cms/classes/Theme.php:300

         *
         */
        $apiResult = Event::fire('cms.theme.getEditTheme', [], true);
        if ($apiResult !== null) {
            return $apiResult;
        }

        $editTheme = self::getEditThemeCodeFromPreference();

        if (!$editTheme) {
            $editTheme = Config::get('cms.edit_theme');
        }

        if (!$editTheme) {
            $editTheme = static::getActiveThemeCode();
        }

        if (!$editTheme) {
            throw new SystemException(Lang::get('cms::lang.theme.edit.not_set'));
        }

        return $editTheme;
    }

    /**
     * getEditThemeCodeFromPreference
     */
    protected static function getEditThemeCodeFromPreference()
    {
        // Check for environment
        if (App::runningInConsole()) {
            return null;
        }

        // Check for auth markers
        if (!BackendAuth::hasSession() && !BackendAuth::hasRemember()) {
            return null;

View on GitHub (pinned to b608633a7e)

Solutions

  1. Set 'activeTheme' => '<theme-dir-name>' in config/cms.php (must match the directory under themes/ exactly)
  2. Activate a theme from the backend (Settings > CMS) so both the active code and the user preference are stored
  3. Verify the theme directory actually exists under themes/ and its name matches the configured code (case-sensitive on Linux)
  4. For programmatic flows, call Theme::setActiveTheme('mysite') before any code path reaches Theme::getEditTheme()

Example fix

// before (config/cms.php)
'activeTheme' => null,

// after
'activeTheme' => 'mysite',
Defensive patterns

Strategy: validation

Validate before calling

$code = Config::get('cms.edit_theme') ?? \Cms\Classes\Theme::getActiveThemeCode();
if (!$code) {
    // configure a theme or abort before any CMS backend code runs
    throw new RuntimeException('No CMS theme configured: set cms.activeTheme in config/cms.php');
}

Try / catch

try { $editTheme = \Cms\Classes\Theme::getEditTheme(); } catch (\System\Classes\BaseException $e) { $editTheme = \Cms\Classes\Theme::load('mysite'); }

Prevention

When it happens

Trigger: Opening any backend area backed by Theme::getEditTheme() (CMS pages/partials/layouts, media, the CMS EditorExtension) on an install where the user has no saved edit-theme preference, config/cms.php defines neither 'edit_theme' nor 'activeTheme', and no active theme code is set in the database.

Common situations: Fresh install where no theme was ever activated; config/cms.php missing or with 'activeTheme' commented out; CI/test environments provisioned without theme seeding; the theme/setting rows wiped during a database migration.

Related errors


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