{"record":{"id":"7146a2b5c023b294","repo":"rectorphp/rector","slug":"the-s-rule-requires-configuration","errorCode":null,"errorMessage":"The \"%s\" rule requires configuration.","messagePattern":"The \"(.+?)\" rule requires configuration\\.","errorType":"validation","errorClass":"InvalidConfigurationException","httpStatus":null,"severity":"error","filePath":"rules/Php80/Rector/Class_/AnnotationToAttributeRector.php","lineNumber":156,"sourceCode":"    }\n}\nCODE_SAMPLE\n, [new AnnotationToAttribute('Symfony\\Component\\Routing\\Annotation\\Route')])]);\n    }\n    /**\n     * @return array<class-string<Node>>\n     */\n    public function getNodeTypes(): array\n    {\n        return [Class_::class, Property::class, Param::class, ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class, Interface_::class];\n    }\n    /**\n     * @param Class_|Property|Param|ClassMethod|Function_|Closure|ArrowFunction|Interface_ $node\n     */\n    public function refactor(Node $node): ?Node\n    {\n        if ($this->annotationsToAttributes === []) {\n            throw new InvalidConfigurationException(sprintf('The \"%s\" rule requires configuration.', self::class));\n        }\n        $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);\n        if (!$phpDocInfo instanceof PhpDocInfo) {\n            return null;\n        }\n        $uses = $this->useImportsResolver->resolveBareUses();\n        // 1. Doctrine annotation classes\n        $annotationAttributeGroups = $this->processDoctrineAnnotationClasses($phpDocInfo, $uses);\n        // 2. bare tags without annotation class, e.g. \"@require\"\n        $genericAttributeGroups = $this->processGenericTags($phpDocInfo);\n        $attributeGroups = array_merge($annotationAttributeGroups, $genericAttributeGroups);\n        if ($attributeGroups === []) {\n            return null;\n        }\n        // 3. Reprint docblock\n        $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);\n        $this->attributeGroupNamedArgumentManipulator->decorate($attributeGroups);\n        $node->attrGroups = array_merge($node->attrGroups, $attributeGroups);","sourceCodeStart":138,"sourceCodeEnd":174,"githubUrl":"https://github.com/rectorphp/rector/blob/408fcb0ff1833e3d26cbc9b04c23a77565814a16/rules/Php80/Rector/Class_/AnnotationToAttributeRector.php#L138-L174","documentation":"AnnotationToAttributeRector is an active, configurable PHP 8.0 rule that rewrites docblock/Doctrine annotations into native attributes (e.g. @Route to #[Route]). It implements ConfigurableRectorInterface and its refactor() first checks the $annotationsToAttributes array (rules/Php80/Rector/Class_/AnnotationToAttributeRector.php:155); when that array is empty the rule was registered without its required configuration and it throws Rector\\Exception\\Configuration\\InvalidConfigurationException. The throw happens while visiting any Class_, Property, Param, ClassMethod, Function_, Closure, ArrowFunction or Interface_ node.","triggerScenarios":"Registering the rule without a mapping: ->withRules([AnnotationToAttributeRector::class]) instead of ->withConfiguredRule(AnnotationToAttributeRector::class, [new AnnotationToAttribute('Symfony\\Component\\Routing\\Annotation\\Route')]), or passing an empty array as the configuration. The exception is raised on the first matching node with a docblock that rector processes.","commonSituations":"Copy-pasting a config snippet that omits the second argument of withConfiguredRule(); migrating an old YAML container config where the annotation list was wired via a setter call; refactoring rector.php and accidentally dropping the AnnotationToAttribute entries.","solutions":["Configure the rule: ->withConfiguredRule(AnnotationToAttributeRector::class, [new AnnotationToAttribute('Symfony\\Component\\Routing\\Annotation\\Route'), ...]) with one AnnotationToAttribute entry per annotation class to convert.","If the rule was enabled by mistake, remove it from withRules() entirely.","Verify each mapped annotation class really is declared as an attribute class in the target dependency - the rule uses reflectionProvider->hasClass()/isAttributeClass() and silently skips classes that do not qualify, which can look like 'no configuration'."],"exampleFix":"// before\nuse Rector\\Php80\\Rector\\Class_\\AnnotationToAttributeRector;\n\nreturn RectorConfig::configure()\n    ->withRules([AnnotationToAttributeRector::class]);\n\n// after\nuse Rector\\Php80\\Rector\\Class_\\AnnotationToAttributeRector;\nuse Rector\\Php80\\ValueObject\\AnnotationToAttribute;\n\nreturn RectorConfig::configure()\n    ->withConfiguredRule(AnnotationToAttributeRector::class, [\n        new AnnotationToAttribute('Symfony\\Component\\Routing\\Annotation\\Route'),\n    ]);","handlingStrategy":"validation","validationCode":"use Rector\\Php80\\ValueObject\\AnnotationToAttribute;\n\n$annotationsToAttributes = [\n    new AnnotationToAttribute('Symfony\\Component\\Routing\\Annotation\\Route'),\n];\nif ($annotationsToAttributes === []) {\n    throw new InvalidArgumentException('AnnotationToAttributeRector requires at least one AnnotationToAttribute entry');\n}\n\nreturn RectorConfig::configure()\n    ->withConfiguredRule(AnnotationToAttributeRector::class, $annotationsToAttributes);","typeGuard":"$ruleReflection = new ReflectionClass($ruleClass);\n$needsConfiguration = $ruleReflection->implementsInterface(\\Rector\\Contract\\Rector\\ConfigurableRectorInterface::class);\n// if true: register with ->withConfiguredRule($ruleClass, $config), never with ->withRules()","tryCatchPattern":"try {\n    exit($rectorApplication->run());\n} catch (\\Rector\\Exception\\Configuration\\InvalidConfigurationException $e) {\n    fwrite(STDERR, 'Rector config error: ' . $e->getMessage() . PHP_EOL);\n    fwrite(STDERR, 'Use ->withConfiguredRule() with an AnnotationToAttribute[] list.' . PHP_EOL);\n    exit(1);\n}","preventionTips":["Register every rule implementing ConfigurableRectorInterface with ->withConfiguredRule(), not ->withRules().","Keep the annotation map in a named $annotationsToAttributes variable and assert it is non-empty before wiring it in.","Run vendor/bin/rector --dry-run in CI after any rector.php edit to surface configuration errors before a full run.","Confirm each mapped annotation class is #[Attribute]-marked in the dependency; rector skips non-attribute classes via isAttributeClass()."],"tags":["rector","php","attributes","annotations","configuration","doctrine"],"backgroundTag":"missing-required-configuration","analyzedSha":"408fcb0ff1833e3d26cbc9b04c23a77565814a16","analyzedAt":"2026-08-21T05:11:02.643Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}