octobercms/october · error · ApplicationException

Unable to a find a primary component "%s" for generating a U

Error message

Unable to a find a primary component "%s" for generating a URL in %s.

What it means

The UrlMaker trait gives a model a magic ->url attribute by finding a CMS page that uses the component named in $urlComponentName (preferring one whose urlComponentProperty, e.g. isPrimary, equals '1'). When no page in the theme contains that component, getUrlPageName() throws this ApplicationException naming the component and the model class. The lookup is cached under cms_url_maker_* keys, invalidated by page file mtime.

Source

Thrown at modules/cms/traits/UrlMaker.php:175

        if ($cached !== false) {
            return static::$urlPageName = array_get($cached, 'fileName');
        }

        // Fallback
        //
        $page = null;
        $useProperty = property_exists($this, 'urlComponentProperty');

        if ($useProperty) {
            $page = Page::whereComponent($this->urlComponentName, $this->urlComponentProperty, '1')->first();
        }

        if (!$useProperty || !$page) {
            $page = Page::withComponent($this->urlComponentName)->first();
        }

        if (!$page) {
            throw new ApplicationException(sprintf(
                'Unable to a find a primary component "%s" for generating a URL in %s.',
                $this->urlComponentName,
                get_class($this)
            ));
        }

        $baseFileName = $page->getBaseFileName();
        $filePath = $page->getFilePath();

        $cached = [
            'path' => $filePath,
            'fileName' => $baseFileName,
            'mtime' => @File::lastModified($filePath)
        ];

        $expiresAt = now()->addMinutes(Config::get('cms.template_cache_ttl', 1440));
        Cache::put($key, serialize($cached), $expiresAt);

View on GitHub (pinned to b608633a7e)

Solutions

  1. Create or restore a page in the ACTIVE theme that uses the component named by $urlComponentName, e.g. add [blogPost] to a page template.
  2. If the model declares $urlComponentProperty (e.g. isPrimary), set that property to '1' on the component instance in the intended primary page.
  3. Keep the component name (and alias) on the page in sync with $urlComponentName - the lookup matches on that name.
  4. After restructuring pages, clear stale lookups: php artisan cache:clear (keys cms_url_maker_*).

Example fix

{# before: themes/demo/pages/blog.htm - no component, $post->url throws #}
url = "/blog"

{# after: primary component present, matches urlComponentName = 'blogPost' #}
url = "/blog/post/:slug"

[blogPost]
slug = "{{ :slug }}"
isPrimary = "1"
Defensive patterns

Strategy: validation

Validate before calling

use Cms\Classes\Page;

// guard before touching $model->url (mirrors the trait's own lookup)
if (!Page::withComponent($post->urlComponentName)->first()) {
    // no page uses the component - skip URL generation or link to a fallback
}

Try / catch

try {
    $url = $post->url;
} catch (ApplicationException $e) {
    $url = null; // render without a link until a primary page exists
}

Prevention

When it happens

Trigger: Accessing $model->url (directly or via a component listing) when the active theme has no page with a matching component - e.g. $urlComponentName = 'blogPost' but no page defines [blogPost]; the primary page was deleted or renamed; the active theme was switched to one lacking the page; the component alias/name drifted from what the trait declares.

Common situations: Plugin installed but its demo pages/components never added to the current theme; production theme switched without porting the primary page; refactors that renamed a component without updating the model's $urlComponentName; cached lookup expiring after the page file was already removed, forcing a rescan that now fails.

Related errors


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