rectorphp/rector · error · RectorRuleNotFoundException

Rule "%s" was not found.%sMake sure it is registered in your

Error message

Rule "%s" was not found.%sMake sure it is registered in your config or in one of the sets

What it means

The terminal case of --only resolution: the namespaced value matched no registered rule AND is not an existing Rector rule class, so OnlyRuleResolver throws RectorRuleNotFoundException telling you to check registration and sets. Unlike the 'exists, but is not registered' variant, here the class itself is unknown to the autoloader -- typo, wrong namespace, or the rule lives in a package/version you do not have.

Source

Thrown at src/Configuration/OnlyRuleResolver.php:77

            $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);
    }
    private function createUnregisteredMessage(string $ruleClass): string
    {
        $shortRuleClass = (string) substr((string) strrchr($ruleClass, '\\'), 1);

View on GitHub (pinned to 408fcb0ff1)

Solutions

  1. Check the class exists in your vendor: grep -r 'class ReadOnlyPropertyRector' vendor/ or php -r "var_dump(class_exists('...'));"
  2. Fix the namespace per your installed version (namespaces moved between major versions, e.g. Rector\Rector... to Rector\<Domain>\Rector...)
  3. If the rule ships in an optional package (rector-symfony, rector-phpunit, rector-doctrine...), composer require it first, then register it
  4. Search the rule short name in your vendor's set files to see where it is registered: grep -rl 'SomeRector' vendor/rector --include='*.php'

Example fix

# before: rule lives in an optional package that is not installed
vendor/bin/rector process src --only="Rector\Symfony\CodeQuality\Rector\ClassMethod\RouteCollectionRector"

# after: install the package, then run
composer require --dev rector/symfony
vendor/bin/rector process src --only="Rector\Symfony\CodeQuality\Rector\ClassMethod\RouteCollectionRector"
Defensive patterns

Strategy: validation

Validate before calling

// verify a rule class exists before passing it to --only
$rule = 'Rector\Symfony\CodeQuality\Rector\ClassMethod\RouteCollectionRector';
if (! class_exists($rule) || ! is_subclass_of($rule, \Rector\Contract\Rector\RectorInterface::class, true)) {
    fwrite(STDERR, "Not an existing Rector rule: {$rule}\n");
    exit(1);
}

Type guard

function isExistingRectorRule(string $class): bool
{
    return class_exists($class)
        && (new ReflectionClass($class))->implementsInterface(\Rector\Contract\Rector\RectorInterface::class)
        && ! (new ReflectionClass($class))->isAbstract();
}

Try / catch

catch \Rector\Exception\Configuration\RectorRuleNotFoundException; on the generic 'was not found' message, verify class_exists(), install any missing rector-* package, fix the namespace, and retry.

Prevention

When it happens

Trigger: Typos in the FQCN; a rule from a newer/older Rector version or from a split package (rector-symfony, rector-phpunit etc.) that is not installed; stale class names copied from outdated blog posts after renames.

Common situations: Upgrading Rector: rules renamed/moved namespaces; using a Symfony/PHPUnit-specific rule without the rector-symfony/rector-phpunit package installed; IDE autocomplete picking a similarly named class.

Related errors


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