{"record":{"id":"4546f993103b876e","repo":"octobercms/october","slug":"route-prefix-must-start-with-a-forward-slash","errorCode":null,"errorMessage":"Route prefix must start with a forward slash (/)","messagePattern":"Route prefix must start with a forward slash \\(/\\)","errorType":"validation","errorClass":"October\\Rain\\Exception\\ValidationException","httpStatus":null,"severity":"warning","filePath":"modules/system/models/SiteDefinition.php","lineNumber":133,"sourceCode":"            'is_enabled_edit' => true,\n            'group_id' => null,\n            'group' => null,\n        ];\n        $site->syncOriginal();\n        return $site;\n    }\n\n    /**\n     * beforeValidate\n     */\n    public function beforeValidate()\n    {\n        if ($this->is_custom_url && !Url::isValidUrl($this->app_url)) {\n            throw new ValidationException(['app_url' => __(\"Please specify a valid URL\")]);\n        }\n\n        if ($this->is_prefixed && (substr($this->route_prefix, 0, 1) !== '/' || $this->route_prefix === '/')) {\n            throw new ValidationException(['route_prefix' => __(\"Route prefix must start with a forward slash (/)\")]);\n        }\n\n        if ($this->is_host_restricted && !$this->isAllowHostsValid()) {\n            throw new ValidationException(['allow_hosts' => __(\"Please specify a valid hostname\")]);\n        }\n\n        $this->fallback_locale = $this->getFallbackLocale($this->locale);\n    }\n\n    /**\n     * getFallbackLocale attempts to extract the fallback language from the locale.\n     * @return string\n     */\n    protected function getFallbackLocale($locale)\n    {\n        if ($position = strpos($locale, '-')) {\n            $target = substr($locale, 0, $position);\n            $available = $this->getLocaleOptions();","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/octobercms/october/blob/b608633a7e8922487d91a8161499020121c3b3bf/modules/system/models/SiteDefinition.php#L115-L151","documentation":"SiteDefinition::beforeValidate() enforces the route prefix format for prefixed multisite sites: when is_prefixed is on, route_prefix must start with '/' and must not be exactly '/'. Any other value (missing slash, trailing-only slash, bare '/' or empty) throws a ValidationException on the route_prefix field.","triggerScenarios":"Saving a site with is_prefixed enabled and route_prefix 'en', 'en/', '/', or an empty string.","commonSituations":"Typing the locale/prefix without the leading slash in the site form; assuming '/' alone is valid for the root; provisioning sites from config where the prefix lost its slash.","solutions":["Set the prefix with a leading slash and a non-empty segment: /en, /de","Disable the 'prefixed' option if the site should not use a route prefix at all","When saving programmatically, normalize before save: '/' . trim($prefix, '/') when non-empty"],"exampleFix":"# before\nroute_prefix: \"en\"\n\n# after\nroute_prefix: \"/en\"","handlingStrategy":"validation","validationCode":"$prefix = trim((string) $site->route_prefix);\nif ($prefix !== '' && $prefix !== '/') {\n    $site->route_prefix = '/' . trim($prefix, '/');\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Enter route prefixes with a leading slash and a non-empty segment (/en)","Normalize config-provided prefixes before saving sites programmatically","Remember '/' alone is invalid — it would match every route"],"tags":["multisite","site","routing","validation"],"backgroundTag":"invalid-route-prefix","analyzedSha":"b608633a7e8922487d91a8161499020121c3b3bf","analyzedAt":"2026-08-21T04:24:57.515Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}