{"record":{"id":"80cbdc1ee45b395d","repo":"octobercms/october","slug":"unable-to-a-find-a-primary-component-s-for-gene","errorCode":null,"errorMessage":"Unable to a find a primary component \"%s\" for generating a URL in %s.","messagePattern":"Unable to a find a primary component \"(.+?)\" for generating a URL in (.+?)\\.","errorType":"exception","errorClass":"ApplicationException","httpStatus":null,"severity":"error","filePath":"modules/cms/traits/UrlMaker.php","lineNumber":175,"sourceCode":"        if ($cached !== false) {\n            return static::$urlPageName = array_get($cached, 'fileName');\n        }\n\n        // Fallback\n        //\n        $page = null;\n        $useProperty = property_exists($this, 'urlComponentProperty');\n\n        if ($useProperty) {\n            $page = Page::whereComponent($this->urlComponentName, $this->urlComponentProperty, '1')->first();\n        }\n\n        if (!$useProperty || !$page) {\n            $page = Page::withComponent($this->urlComponentName)->first();\n        }\n\n        if (!$page) {\n            throw new ApplicationException(sprintf(\n                'Unable to a find a primary component \"%s\" for generating a URL in %s.',\n                $this->urlComponentName,\n                get_class($this)\n            ));\n        }\n\n        $baseFileName = $page->getBaseFileName();\n        $filePath = $page->getFilePath();\n\n        $cached = [\n            'path' => $filePath,\n            'fileName' => $baseFileName,\n            'mtime' => @File::lastModified($filePath)\n        ];\n\n        $expiresAt = now()->addMinutes(Config::get('cms.template_cache_ttl', 1440));\n        Cache::put($key, serialize($cached), $expiresAt);\n","sourceCodeStart":157,"sourceCodeEnd":193,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/cms/traits/UrlMaker.php#L157-L193","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Create or restore a page in the ACTIVE theme that uses the component named by $urlComponentName, e.g. add [blogPost] to a page template.","If the model declares $urlComponentProperty (e.g. isPrimary), set that property to '1' on the component instance in the intended primary page.","Keep the component name (and alias) on the page in sync with $urlComponentName - the lookup matches on that name.","After restructuring pages, clear stale lookups: php artisan cache:clear (keys cms_url_maker_*)."],"exampleFix":"{# before: themes/demo/pages/blog.htm - no component, $post->url throws #}\nurl = \"/blog\"\n\n{# after: primary component present, matches urlComponentName = 'blogPost' #}\nurl = \"/blog/post/:slug\"\n\n[blogPost]\nslug = \"{{ :slug }}\"\nisPrimary = \"1\"","handlingStrategy":"validation","validationCode":"use Cms\\Classes\\Page;\n\n// guard before touching $model->url (mirrors the trait's own lookup)\nif (!Page::withComponent($post->urlComponentName)->first()) {\n    // no page uses the component - skip URL generation or link to a fallback\n}","typeGuard":null,"tryCatchPattern":"try {\n    $url = $post->url;\n} catch (ApplicationException $e) {\n    $url = null; // render without a link until a primary page exists\n}","preventionTips":["Ship a default page containing your component with isPrimary = 1 as part of plugin/theme install.","Keep $urlComponentName in sync when renaming components across versions.","Smoke-test any page or component listing that outputs $model->url after switching the active theme.","Clear cms_url_maker_* cache entries after restructuring pages."],"tags":["cms","url-generation","component","page","theme"],"backgroundTag":"component-not-found","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}