symfony/routing · error · InvalidArgumentException

You must define a "path" for the route

Error message

You must define a "path" for the route "%s" in file "%s".

What it means

Every route definition in a routing file must specify a 'path' (the URL pattern) or be an import via 'resource'. When an entry has neither, ContentLoaderTrait's validate() throws InvalidArgumentException because the entry cannot produce any route.

Solutions

  1. Add the missing 'path' key with the URL pattern to the route entry
  2. If the entry should import another file, replace 'path' with a 'resource' key pointing at it
  3. Fix YAML indentation so 'path' belongs to the intended route entry

Example fix

# before
app_blog:
    controller: App\Controller\BlogController::index

# after
app_blog:
    path: /blog
    controller: App\Controller\BlogController::index
Defensive patterns

Strategy: validation

Validate before calling

foreach ($routes as $name => $config) {
    if (!isset($config['path']) && !isset($config['resource'])) {
        throw new \LogicException(sprintf('Route "%s" needs a "path" or "resource".', $name));
    }
}

Type guard

function hasRouteTarget(array $config): bool { return isset($config['path']) || isset($config['resource']); }

Try / catch

try { $collection = $loader->load($file, 'yaml'); } catch (\InvalidArgumentException $e) { /* route entry missing 'path'; fix config */ }

Prevention

When it happens

Trigger: A routing file entry that provides only keys like 'controller', 'defaults' or 'type' but no 'path' and no 'resource' — commonly after deleting the path line or a YAML indentation error that orphaned the entry.

Common situations: YAML mis-indentation turning a route's 'path' into a sibling key; incomplete copy-paste of a route block; renaming 'path' to 'url' by mistake; route entries left empty after refactoring.

Understand the failure class

Background: "is required", "must be set", "missing required field": configuration validation errors across open-source libraries — this error's family across 36 libraries.

Related errors


AI-assisted analysis of symfony/routing@83fa223250 (2026-09-14). Data as JSON: /api/errors/dd13166437b3b05f. Report an issue: GitHub.

Appendix: source

Thrown at Loader/ContentLoaderTrait.php:226

        if (!\is_array($config)) {
            throw new \InvalidArgumentException(\sprintf('The definition of "%s" in "%s" must be an array.', $name, $path));
        }
        if (isset($config['alias'])) {
            $this->validateAlias($config, $name, $path);

            return;
        }
        if ($extraKeys = array_diff(array_keys($config), self::AVAILABLE_KEYS)) {
            throw new \InvalidArgumentException(\sprintf('The routing file "%s" contains unsupported keys for "%s": "%s". Expected one of: "%s".', $path, $name, implode('", "', $extraKeys), implode('", "', self::AVAILABLE_KEYS)));
        }
        if (isset($config['resource']) && isset($config['path'])) {
            throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "resource" key and the "path" key for "%s". Choose between an import and a route definition.', $path, $name));
        }
        if (!isset($config['resource']) && isset($config['type'])) {
            throw new \InvalidArgumentException(\sprintf('The "type" key for the route definition "%s" in "%s" is unsupported. It is only available for imports in combination with the "resource" key.', $name, $path));
        }
        if (!isset($config['resource']) && !isset($config['path'])) {
            throw new \InvalidArgumentException(\sprintf('You must define a "path" for the route "%s" in file "%s".', $name, $path));
        }
        if (isset($config['controller']) && isset($config['defaults']['_controller'])) {
            throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "controller" key and the defaults key "_controller" for "%s".', $path, $name));
        }
        if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {
            throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "stateless" key and the defaults key "_stateless" for "%s".', $path, $name));
        }
        if (isset($config['firewall']) && isset($config['defaults']['_firewall'])) {
            throw new \InvalidArgumentException(\sprintf('The routing file "%s" must not specify both the "firewall" key and the defaults key "_firewall" for "%s".', $path, $name));
        }
    }

    /**
     * Validates that an alias definition only carries the `alias` and `deprecated` keys.
     *
     * @throws \InvalidArgumentException If one of the provided config keys is not supported,
     *                                   something is missing or the combination is nonsense
     */

View on GitHub (pinned to 83fa223250)