{"record":{"id":"6db2fdbe7a42f96d","repo":"symfony/routing","slug":"the-routing-file-s-must-not-specify-both-the-stateless-key","errorCode":null,"errorMessage":"The routing file \"%s\" must not specify both the \"stateless\" key and the defaults key \"_stateless\" for \"%s\".","messagePattern":"The routing file \"(.+?)\" must not specify both the \"stateless\" key and the defaults key \"_stateless\" for \"(.+?)\"\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Loader/ContentLoaderTrait.php","lineNumber":232,"sourceCode":"            return;\n        }\n        if ($extraKeys = array_diff(array_keys($config), self::AVAILABLE_KEYS)) {\n            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)));\n        }\n        if (isset($config['resource']) && isset($config['path'])) {\n            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));\n        }\n        if (!isset($config['resource']) && isset($config['type'])) {\n            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));\n        }\n        if (!isset($config['resource']) && !isset($config['path'])) {\n            throw new \\InvalidArgumentException(\\sprintf('You must define a \"path\" for the route \"%s\" in file \"%s\".', $name, $path));\n        }\n        if (isset($config['controller']) && isset($config['defaults']['_controller'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"controller\" key and the defaults key \"_controller\" for \"%s\".', $path, $name));\n        }\n        if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"stateless\" key and the defaults key \"_stateless\" for \"%s\".', $path, $name));\n        }\n        if (isset($config['firewall']) && isset($config['defaults']['_firewall'])) {\n            throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify both the \"firewall\" key and the defaults key \"_firewall\" for \"%s\".', $path, $name));\n        }\n    }\n\n    /**\n     * Validates that an alias definition only carries the `alias` and `deprecated` keys.\n     *\n     * @throws \\InvalidArgumentException If one of the provided config keys is not supported,\n     *                                   something is missing or the combination is nonsense\n     */\n    private function validateAlias(array $config, string $name, string $path): void\n    {\n        foreach ($config as $key => $value) {\n            if (!\\in_array($key, ['alias', 'deprecated'], true)) {\n                throw new \\InvalidArgumentException(\\sprintf('The routing file \"%s\" must not specify other keys than \"alias\" and \"deprecated\" for \"%s\".', $path, $name));\n            }","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Loader/ContentLoaderTrait.php#L214-L250","documentation":"Statelessness can be declared with the route-level 'stateless' key or via defaults['_stateless'], never both. ContentLoaderTrait::validate() throws InvalidArgumentException when both appear, since the two settings could disagree and Symfony refuses to guess.","triggerScenarios":"A route entry containing both 'stateless: true' (top-level) and 'defaults: { _stateless: true }' in the same routing file.","commonSituations":"Upgrading configs from Symfony versions where _stateless in defaults was the documented form; mixing snippets from docs of different versions; merge conflicts resolved by keeping both lines.","solutions":["Keep the top-level 'stateless' key and remove defaults['_stateless']","Or remove the top-level 'stateless' key if you intentionally rely on the defaults form (older style)","Grep routing files for '_stateless' after version upgrades"],"exampleFix":"# before\napp_api:\n    path: /api\n    stateless: true\n    defaults:\n        _stateless: true\n\n# after\napp_api:\n    path: /api\n    stateless: true","handlingStrategy":"validation","validationCode":"if (isset($config['stateless']) && isset($config['defaults']['_stateless'])) {\n    throw new \\LogicException('Use either \"stateless\" or defaults._stateless, not both.');\n}","typeGuard":"function hasSingleStateless(array $config): bool { return !(isset($config['stateless']) && isset($config['defaults']['_stateless'])); }","tryCatchPattern":"try { $collection = $loader->load($file, 'yaml'); } catch (\\InvalidArgumentException $e) { /* duplicate stateless declaration; dedupe config */ }","preventionTips":["Use only the top-level 'stateless' key on modern Symfony","Remove legacy defaults._stateless after upgrades","Add a config lint step to CI"],"tags":["symfony","routing","config-validation"],"backgroundTag":"conflicting-config-options","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"}