rectorphp/rector · error · RectorRuleNotFoundException

Rule "%s" exists, but is not registered in your Rector confi

Error message

Rule "%s" exists, but is not registered in your Rector config.%sRegister it in your rector.php:

    ->withRules([%s::class])

What it means

When a --only value with a namespace matches no registered rule, OnlyRuleResolver checks whether the class exists and implements RectorInterface; if so, the rule is real but simply not registered in your container, and it throws RectorRuleNotFoundException with a ready-to-paste withRules() snippet. The fix is registration, not spelling -- the class string you typed is already correct.

Source

Thrown at src/Configuration/OnlyRuleResolver.php:73

            throw new RectorRuleNameAmbiguousException($message);
        }
        if (strpos($rule, '\\') === \false) {
            // the shell has eaten unescaped backslashes, e.g. --only=\Rector\Some\Rule
            $flattenMatching = [];
            foreach ($this->rectors as $rector) {
                if (str_replace('\\', '', get_class($rector)) === $rule) {
                    $flattenMatching[] = get_class($rector);
                }
            }
            $flattenMatching = array_unique($flattenMatching);
            if (count($flattenMatching) === 1) {
                return $flattenMatching[0];
            }
            $message = sprintf('Rule "%s" was not found.%sThe rule has no namespace. Make sure to escape the backslashes, and add quotes around the rule name: --only="My\Rector\Rule"', $rule, \PHP_EOL);
        } else {
            // the rule class exists, it is just missing in the config
            if ($this->isRectorRuleClass($rule)) {
                throw new RectorRuleNotFoundException($this->createUnregisteredMessage($rule));
            }
            $message = sprintf('Rule "%s" was not found.%sMake sure it is registered in your config or in one of the sets', $rule, \PHP_EOL);
        }
        throw new RectorRuleNotFoundException($message);
    }
    /**
     * Is this an existing rule class, that is just not registered in the config?
     */
    private function isRectorRuleClass(string $className): bool
    {
        if (!class_exists($className)) {
            return \false;
        }
        $reflectionClass = new ReflectionClass($className);
        if ($reflectionClass->isAbstract()) {
            return \false;
        }
        return $reflectionClass->implementsInterface(RectorInterface::class);

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Register the rule as the message suggests: add ->withRules([ReadOnlyPropertyRector::class]) to rector.php (copy the snippet from the exception)
  2. Or load the set that ships it, e.g. ->withPhpSets() / ->withPhpLevel(...), instead of naming the rule individually
  3. Verify registration first: search rector.php (and imported configs) for the class short name

Example fix

// before
return RectorConfig::configure()
    ->withPaths([__DIR__ . '/src']);
// vendor/bin/rector process src --only="Rector\Php81\Rector\Property\ReadOnlyPropertyRector"

// after
return RectorConfig::configure()
    ->withPaths([__DIR__ . '/src'])
    ->withRules([\Rector\Php81\Rector\Property\ReadOnlyPropertyRector::class]);
Defensive patterns

Strategy: validation

Validate before calling

// in rector.php, reference rules via ::class constants so typos surface as fatal class loads
use Rector\Php81\Rector\Property\ReadOnlyPropertyRector;
return RectorConfig::configure()
    ->withRules([ReadOnlyPropertyRector::class]);

Try / catch

catch \Rector\Exception\Configuration\RectorRuleNotFoundException; when the message contains 'exists, but is not registered', register the rule via withRules() (or load its set) and re-run.

Prevention

When it happens

Trigger: Running --only="Rector\Php81\Rector\Property\ReadOnlyPropertyRector" while rector.php registers no set that includes it (no withPhpSets/withPhpLevel, or the relevant set was removed during a config cleanup).

Common situations: Trying a rule you saw in docs/changelog without loading its set; configs that were trimmed to a tiny withRules() list; rule moved to a level/set you no longer load after an upgrade.

Related errors


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