{"record":{"id":"3820ed48681e0a59","repo":"symfony/routing","slug":"collection-s-is-missing-prefixes-for-locale-s-s","errorCode":null,"errorMessage":"Collection \"%s\" is missing prefixes for locale(s) \"%s\".","messagePattern":"Collection \"(.+?)\" is missing prefixes for locale\\(s\\) \"(.+?)\"\\.","errorType":"exception","errorClass":"LogicException","httpStatus":null,"severity":"error","filePath":"Loader/Configurator/CollectionConfigurator.php","lineNumber":86,"sourceCode":"        return new self($this->collection, $this->name.$name, $this, $this->prefixes);\n    }\n\n    /**\n     * Sets the prefix to add to the path of all child routes.\n     *\n     * @param string|array $prefix the prefix, or the localized prefixes\n     *\n     * @return $this\n     */\n    final public function prefix(string|array $prefix, bool $trailingSlashOnRoot = true): static\n    {\n        $this->trailingSlashOnRoot = $trailingSlashOnRoot;\n\n        if (\\is_array($prefix)) {\n            if (null === $this->parentPrefixes) {\n                // no-op\n            } elseif ($missing = array_diff_key($this->parentPrefixes, $prefix)) {\n                throw new \\LogicException(\\sprintf('Collection \"%s\" is missing prefixes for locale(s) \"%s\".', $this->name, implode('\", \"', array_keys($missing))));\n            } else {\n                foreach ($prefix as $locale => $localePrefix) {\n                    if (!isset($this->parentPrefixes[$locale])) {\n                        throw new \\LogicException(\\sprintf('Collection \"%s\" with locale \"%s\" is missing a corresponding prefix in its parent collection.', $this->name, $locale));\n                    }\n\n                    $prefix[$locale] = $this->parentPrefixes[$locale].$localePrefix;\n                }\n            }\n            $this->prefixes = $prefix;\n            $this->route->setPath('/');\n        } else {\n            $this->prefixes = null;\n            $this->route->setPath($prefix);\n        }\n\n        return $this;\n    }","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Loader/Configurator/CollectionConfigurator.php#L68-L104","documentation":"CollectionConfigurator::prefix() supports locale-keyed prefixes. When a parent collection already has locale prefixes, a child prefix array must cover every parent locale. Missing locales are detected via array_diff_key and throw LogicException naming the collection and locales.","triggerScenarios":"$collection->prefix(['en' => '/en']) (or ->prefix(...)) on a nested collection whose parent was prefixed with locales ['en','nl'], but the child prefix omits 'nl'.","commonSituations":"Localized route groups where a sub-collection adds a new parent locale without updating all children; partially translated route trees; copying a ->prefix() call between collections.","solutions":["Add the missing locale keys to the child ->prefix([...]) call","Remove the extra locale from the parent collection's prefix","Make both parent and child prefix arrays use identical locale keys"],"exampleFix":"// before\n$collection->collection('blog')->prefix(['en' => '/en']); // parent has en+nl\n// after\n$collection->collection('blog')->prefix(['en' => '/en', 'nl' => '/nl']);","handlingStrategy":"validation","validationCode":"$missing = array_diff_key($parentPrefixes, $childPrefix); if ($missing) { /* extend child prefix before calling ->prefix() */ }","typeGuard":"function coversParentLocales(array $parent, array $child): bool { return !array_diff_key($parent, $child); }","tryCatchPattern":"try { $routes = $loader->load($file); } catch (\\LogicException $e) { if (str_contains($e->getMessage(), 'missing prefixes')) { /* sync collection prefixes */ } throw $e; }","preventionTips":["Define the app locale list once and build all prefix arrays from it","Audit nested ->prefix() calls when adding locales","CI route-loading smoke test"],"tags":["routing","i18n","localized-routes"],"backgroundTag":"missing-required-config-field","analyzedSha":"83fa223250b50f4f018c011e101c330e65ac63cc","analyzedAt":"2026-09-14T03:19:46.280Z","contentChangedAt":"2026-09-14T03:19:46.280Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}