getgrav/grav · error · RuntimeException

{theme} theme could not be found

Error message

{theme} theme could not be found

What it means

Thrown by Themes::initTheme() when $themes->load() fails with an InvalidArgumentException while resolving the current theme through the theme:// stream. It means the theme configured as current (system.pages.theme) could not be located or loaded, so the frontend has nothing to render with. Grav deliberately keeps admin and API requests alive when a theme is missing (load() closes with a 500 only for frontend requests), so hitting this RuntimeException usually means the theme stream itself failed to resolve the theme's files.

Source

Thrown at system/src/Grav/Common/Themes.php:81

        $themes = $this->grav['themes'];
        $themes->configure();

        $this->initTheme();
    }

    /**
     * @return void
     */
    public function initTheme()
    {
        if ($this->inited === false) {
            /** @var Themes $themes */
            $themes = $this->grav['themes'];

            try {
                $instance = $themes->load();
            } catch (InvalidArgumentException) {
                throw new RuntimeException($this->current() . ' theme could not be found');
            }

            // Register autoloader.
            if (method_exists($instance, 'autoload')) {
                $instance->autoload();
            }

            // Register event listeners.
            if ($instance instanceof EventSubscriberInterface) {
                /** @var EventDispatcher $events */
                $events = $this->grav['events'];
                $events->addSubscriber($instance);
            }

            // Register blueprints.
            if (is_dir('theme://blueprints/pages')) {
                /** @var UniformResourceLocator $locator */
                $locator = $this->grav['locator'];

View on GitHub (pinned to 6040efed04)

Solutions

  1. Compare the value of pages.theme in user/config/system.yaml with the folder names under user/themes/ and make them match exactly (case included)
  2. Install or restore the theme: bin/gpm install <name>, or re-upload it so the folder name equals the theme name
  3. Rename the mismatched folder (mv user/themes/mytheme-master user/themes/mytheme) and run bin/grav clearcache
  4. If the admin backend is reachable, temporarily switch to an installed theme (e.g. quark) and fix the missing one at leisure

Example fix

# before: system.yaml has pages.theme: quark but the folder is quark-master
user/themes/quark-master/quark-master.yaml

# after
mv user/themes/quark-master user/themes/quark
bin/grav clearcache
Defensive patterns

Strategy: validation

Validate before calling

// verify the configured theme exists before init
$name = $grav['config']->get('system.pages.theme');
$locator = $grav['locator'];
if (!$name || !$locator->findResource("themes://{$name}", true)) {
    // fail fast with an actionable message or fall back to a known-good theme
    $grav['config']->set('system.pages.theme', 'quark');
}

Try / catch

try { $themes->initTheme(); } catch (RuntimeException $e) { // render maintenance page, log theme name
    echo 'Theme unavailable: ' . $e->getMessage(); }

Prevention

When it happens

Trigger: system.pages.theme: mytheme in user/config/system.yaml while user/themes/mytheme/ does not exist; theme folder renamed or with different letter-case on a case-sensitive filesystem; a theme installed from a GitHub zip as mytheme-master while config expects mytheme; theme files missing after a git clone because user/themes was gitignored; a broken theme:// stream registration produced by bad streams.schemes config.

Common situations: Moving a site between environments without vendoring themes; deleting a still-selected theme from the admin; typos or case mismatches between the configured theme name and the installed folder name; deploying partial artifacts that omit user/themes.

Related errors


AI-assisted analysis of getgrav/grav@6040efed04 (2026-08-17). Data as JSON: /api/errors/a711b8e716d127ed. Report an issue: GitHub.