symfony/routing · error · InvalidArgumentException
The return value in config file
Error message
The return value in config file "%s" is expected to be a RouteCollection, an array or a configurator callable, but got "%s".
What it means
PhpFileLoader expects a route config PHP file to return a RouteCollection, an array of route definitions, or an invokable configurator object. Any other return value triggers this InvalidArgumentException, telling you the actual type returned via get_debug_type().
Solutions
- Make the config file return one of: a RouteCollection, an array (with ->setDefault etc. or nested route arrays), or an invokable configurator.
- If returning null, add the missing return statement.
- Check with get_debug_type in the message what type was actually returned and correct it.
Example fix
// before <?php // config/routes/x.php $collection = new RouteCollection(); $collection->add(...); // (no return -> null) // after <?php $collection = new RouteCollection(); $collection->add(...); return $collection;
Defensive patterns
Strategy: validation
Validate before calling
$result = require $path;
if (!$result instanceof RouteCollection && !is_array($result) && !(is_object($result) && is_callable($result))) {
throw new \InvalidArgumentException(sprintf('%s must return RouteCollection|array|callable, got %s', $path, get_debug_type($result)));
} Try / catch
try { $collection = $phpLoader->load($path); } catch (\InvalidArgumentException $e) { if (str_contains($e->getMessage(), 'expected to be a RouteCollection')) { throw new \RuntimeException("Bad route config file: $path", 0, $e); } throw $e; } Prevention
- Always end route config PHP files with an explicit return.
- Return RouteCollection, a plain route array, or an invokable configurator — nothing else.
- Lint route config files in CI by loading them with PhpFileLoader.
When it happens
Trigger: A config/routes/*.php file whose return statement yields e.g. a string, null, true/false, or an unrelated object (non-callable), while loading routes through PhpFileLoader.
Common situations: Hand-writing route PHP files and forgetting the return statement (returns null); returning a builder object instead of the collection; migrating YAML routes and mixing in plain values.
Related errors
- Parameter " " for route " " must match " " (" " given) to…
- Parameters for route
- Route aliases cannot be used on non-invokable class
- The " ()" method must not be called.
- Namespace " " is not a valid PSR-4 prefix.
AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14).
Data as JSON: /api/errors/f688b372b33d185f.
Report an issue: GitHub.
Appendix: source
Thrown at Loader/PhpFileLoader.php:64
}
// the closure forbids access to the private scope in the included file
$loader = $this;
$load = \Closure::bind(static function ($file) use ($loader) {
return include $file;
}, null, null);
if (1 === $result = $load($path)) {
$result = null;
}
if (\is_object($result) && \is_callable($result)) {
$collection = $this->callConfigurator($result, $path, $file);
} elseif (\is_array($result)) {
$collection = new RouteCollection();
$this->loadContent($collection, $result, $path, $file);
} elseif (!($collection = $result) instanceof RouteCollection) {
throw new InvalidArgumentException(\sprintf('The return value in config file "%s" is expected to be a RouteCollection, an array or a configurator callable, but got "%s".', $path, get_debug_type($result)));
}
$collection->addResource(new FileResource($path));
return $collection;
}
public function supports(mixed $resource, ?string $type = null): bool
{
return \is_string($resource) && 'php' === pathinfo($resource, \PATHINFO_EXTENSION) && (!$type || 'php' === $type);
}
/**
* @param-immediately-invoked-callable $callback
*/
protected function callConfigurator(callable $callback, string $path, string $file): RouteCollection
{
$collection = new RouteCollection();View on GitHub (pinned to 83fa223250)