rectorphp/rector · error · InvalidConfigurationException

The "%s" rule requires configuration.

Error message

The "%s" rule requires configuration.

What it means

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.

Source

Thrown at rules/Php80/Rector/Class_/AnnotationToAttributeRector.php:156

    }
}
CODE_SAMPLE
, [new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route')])]);
    }
    /**
     * @return array<class-string<Node>>
     */
    public function getNodeTypes(): array
    {
        return [Class_::class, Property::class, Param::class, ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class, Interface_::class];
    }
    /**
     * @param Class_|Property|Param|ClassMethod|Function_|Closure|ArrowFunction|Interface_ $node
     */
    public function refactor(Node $node): ?Node
    {
        if ($this->annotationsToAttributes === []) {
            throw new InvalidConfigurationException(sprintf('The "%s" rule requires configuration.', self::class));
        }
        $phpDocInfo = $this->phpDocInfoFactory->createFromNode($node);
        if (!$phpDocInfo instanceof PhpDocInfo) {
            return null;
        }
        $uses = $this->useImportsResolver->resolveBareUses();
        // 1. Doctrine annotation classes
        $annotationAttributeGroups = $this->processDoctrineAnnotationClasses($phpDocInfo, $uses);
        // 2. bare tags without annotation class, e.g. "@require"
        $genericAttributeGroups = $this->processGenericTags($phpDocInfo);
        $attributeGroups = array_merge($annotationAttributeGroups, $genericAttributeGroups);
        if ($attributeGroups === []) {
            return null;
        }
        // 3. Reprint docblock
        $this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
        $this->attributeGroupNamedArgumentManipulator->decorate($attributeGroups);
        $node->attrGroups = array_merge($node->attrGroups, $attributeGroups);

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Configure the rule: ->withConfiguredRule(AnnotationToAttributeRector::class, [new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route'), ...]) with one AnnotationToAttribute entry per annotation class to convert.
  2. If the rule was enabled by mistake, remove it from withRules() entirely.
  3. 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'.

Example fix

// before
use Rector\Php80\Rector\Class_\AnnotationToAttributeRector;

return RectorConfig::configure()
    ->withRules([AnnotationToAttributeRector::class]);

// after
use Rector\Php80\Rector\Class_\AnnotationToAttributeRector;
use Rector\Php80\ValueObject\AnnotationToAttribute;

return RectorConfig::configure()
    ->withConfiguredRule(AnnotationToAttributeRector::class, [
        new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route'),
    ]);
Defensive patterns

Strategy: validation

Validate before calling

use Rector\Php80\ValueObject\AnnotationToAttribute;

$annotationsToAttributes = [
    new AnnotationToAttribute('Symfony\Component\Routing\Annotation\Route'),
];
if ($annotationsToAttributes === []) {
    throw new InvalidArgumentException('AnnotationToAttributeRector requires at least one AnnotationToAttribute entry');
}

return RectorConfig::configure()
    ->withConfiguredRule(AnnotationToAttributeRector::class, $annotationsToAttributes);

Type guard

$ruleReflection = new ReflectionClass($ruleClass);
$needsConfiguration = $ruleReflection->implementsInterface(\Rector\Contract\Rector\ConfigurableRectorInterface::class);
// if true: register with ->withConfiguredRule($ruleClass, $config), never with ->withRules()

Try / catch

try {
    exit($rectorApplication->run());
} catch (\Rector\Exception\Configuration\InvalidConfigurationException $e) {
    fwrite(STDERR, 'Rector config error: ' . $e->getMessage() . PHP_EOL);
    fwrite(STDERR, 'Use ->withConfiguredRule() with an AnnotationToAttribute[] list.' . PHP_EOL);
    exit(1);
}

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Related errors


AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21). Data as JSON: /api/errors/7146a2b5c023b294. Report an issue: GitHub.