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
- Register the rule as the message suggests: add ->withRules([ReadOnlyPropertyRector::class]) to rector.php (copy the snippet from the exception)
- Or load the set that ships it, e.g. ->withPhpSets() / ->withPhpLevel(...), instead of naming the rule individually
- 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
- Use ::class imports instead of string literals in withRules()
- When testing a rule from docs, also load the set that ships it (e.g. withPhpSets())
- Keep --only for temporarily narrowing an already-registered rule set
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
- Short rule name "%s" is ambiguous. Specify the full rule nam
- Rule "%s" was not found.%sThe rule has no namespace. Make su
- Rule "%s" was not found.%sMake sure it is registered in your
- "%s" rule is deprecated, as inverting nested ifs to early re
- "%s" rule is deprecated, as splitting a single condition int
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/2056c6107391f4af.
Report an issue: GitHub.