{"record":{"id":"953d2ffba26c9485","repo":"symfony/routing","slug":"the-type-key-for-the-route-definition-s-in-s-is-unsupported","errorCode":null,"errorMessage":"The \"type\" key for the route definition \"%s\" in \"%s\" is unsupported. It is only available for imports in combination with the \"resource\" key.","messagePattern":"The \"type\" key for the route definition \"(.+?)\" in \"(.+?)\" is unsupported\\. It is only available for imports in combination with the \"resource\" key\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"Loader/ContentLoaderTrait.php","lineNumber":223,"sourceCode":"     */\n    private function validate(mixed $config, string $name, string $path): void\n    {\n        if (!\\is_array($config)) {\n            throw new \\InvalidArgumentException(\\sprintf('The definition of \"%s\" in \"%s\" must be an array.', $name, $path));\n        }\n        if (isset($config['alias'])) {\n            $this->validateAlias($config, $name, $path);\n\n            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     *","sourceCodeStart":205,"sourceCodeEnd":241,"githubUrl":"https://github.com/symfony/routing/blob/83fa223250b50f4f018c011e101c330e65ac63cc/Loader/ContentLoaderTrait.php#L205-L241","documentation":"Symfony's routing loader rejects a 'type' key on a route entry that does not also define 'resource'. The 'type' key exists only to select a custom loader for imports; a plain route definition (with 'path') has no loader to select, so the key is meaningless and the validate() method of ContentLoaderTrait throws InvalidArgumentException to catch the config mistake early.","triggerScenarios":"Loading a YAML/XML/PHP routing file whose entry has 'type' (e.g. type: attribute) but no 'resource' key — i.e. a direct route definition carrying a loader type.","commonSituations":"Copy-pasting an import block and editing 'resource' into 'path' while leaving 'type' behind; upgrading from old configs where 'type: annotation' was tolerated; hand-written routes that mimicked import syntax.","solutions":["Remove the 'type' key from the route definition — plain routes do not need a loader type","If a loader type is actually needed, change the entry to an import: keep 'type' and add a 'resource' key","Remove 'path' and restore 'resource' if the entry was meant to import routes"],"exampleFix":"# before\napp_blog:\n    path: /blog\n    type: attribute\n\n# after\napp_blog:\n    path: /blog\n    controller: App\\Controller\\BlogController::index","handlingStrategy":"validation","validationCode":"if (isset($config['type']) && !isset($config['resource'])) {\n    throw new \\InvalidArgumentException(sprintf('Route \"%s\": \"type\" requires a \"resource\" key (import).', $name));\n}","typeGuard":"function isImportWithValidType(array $config): bool { return !isset($config['type']) || isset($config['resource']); }","tryCatchPattern":"try { $collection = $loader->load($file, 'yaml'); } catch (\\InvalidArgumentException $e) { /* fix routing config referenced in $e->getMessage() */ }","preventionTips":["Never put 'type' on plain route definitions","Reserve 'type' for imports that need a custom loader","Lint routing files in CI (e.g. debug:router or config validation)"],"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"}