flarum/framework · error · RuntimeException
Route $name already exists
Error message
Route $name already exists
What it means
Flarum's RouteCollection stores routes keyed by unique name. addRoute() throws this RuntimeException when you try to register a route whose $name is already taken, because duplicate names would make reverse URL generation (getPath) ambiguous. It is an intentional registration-time guard, not a runtime failure.
Solutions
- Rename one of the routes so each name is unique across the application.
- Call removeRoute($name) before re-registering if overwriting is intended.
- Check which extension(s) register the colliding name (search for the route name string in registered extensions).
- Ensure route registration code runs only once (e.g. not inside a loop or a repeatedly-invoked boot hook).
Example fix
// before
$routes->get('/forum', 'index', IndexHandler::class);
$routes->get('/', 'index', HomeHandler::class); // RuntimeException
// after
$routes->get('/forum', 'forum.index', IndexHandler::class);
$routes->get('/', 'home.index', HomeHandler::class); Defensive patterns
Strategy: validation
Validate before calling
if (array_key_exists($name, $routes->getRoutes())) {
$routes->removeRoute($name); // or skip/throw your own clearer error
}
$routes->get($path, $name, $handler); Type guard
function routeNameIsFree(RouteCollection $routes, string $name): bool {
return !array_key_exists($name, $routes->getRoutes());
} Try / catch
try {
$routes->get($path, $name, $handler);
} catch (\RuntimeException $e) {
if (str_contains($e->getMessage(), 'already exists')) {
$routes->removeRoute($name)->get($path, $name, $handler);
} else {
throw $e;
}
} Prevention
- Prefix route names with the extension id (e.g. 'acme.feature') to guarantee uniqueness.
- Centralize route name strings in constants.
- Never run route registration code twice per request.
When it happens
Trigger: Calling addRoute(), get(), post(), put(), patch() or delete() twice with the same route name on the same RouteCollection — e.g. two extensions registering a route named 'index', or re-running a route registration closure on every request without a fresh collection.
Common situations: Two extensions both registering a default frontend route with the same name; copy-pasted route registration code where the second call forgot to change the name; boot code executed twice due to a service provider being registered multiple times.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- Could not generate URL for route '$routeName': no value…
- Route $name not found
- Both text and html views must be provided to send an email…
- Unable to resolve extender for '.$value->var::class
- You cannot disable the default language pack!
AI-assisted analysis of flarum/framework@4b939f6853 (2026-09-15).
Data as JSON: /api/errors/a7dee0d6c0891683.
Report an issue: GitHub.
Appendix: source
Thrown at framework/core/src/Http/RouteCollection.php:61
public function put(string $path, string $name, callable|string $handler): self
{
return $this->addRoute('PUT', $path, $name, $handler);
}
public function patch(string $path, string $name, callable|string $handler): self
{
return $this->addRoute('PATCH', $path, $name, $handler);
}
public function delete(string $path, string $name, callable|string $handler): self
{
return $this->addRoute('DELETE', $path, $name, $handler);
}
public function addRoute(string $method, string $path, string $name, callable|string $handler): self
{
if (isset($this->routes[$name])) {
throw new \RuntimeException("Route $name already exists");
}
$this->routes[$name] = $this->pendingRoutes[$name] = compact('method', 'path', 'handler');
return $this;
}
public function removeRoute(string $name): self
{
unset($this->routes[$name], $this->pendingRoutes[$name]);
return $this;
}
protected function applyRoutes(): void
{
foreach ($this->pendingRoutes as $name => $route) {
$routeDatas = $this->routeParser->parse($route['path']);View on GitHub (pinned to 4b939f6853)