rectorphp/rector · error · InvalidConfigurationException
Set provider "%s" must implement "%s"
Error message
Set provider "%s" must implement "%s"
What it means
RectorConfigBuilder::withSetProviders(string ...$setProviders) registers classes that supply extra rule sets. Each class-string is verified with is_a($setProvider, SetProviderInterface::class, true); a class that does not implement Rector\Set\SetProviderInterface throws InvalidConfigurationException naming the offending class and the required interface.
Source
Thrown at src/Configuration/RectorConfigBuilder.php:807
$this->reportUnusedSkips = $report;
return $this;
}
public function withEditorUrl(string $editorUrl): self
{
$this->editorUrl = $editorUrl;
return $this;
}
/**
* @param class-string<SetProviderInterface> ...$setProviders
*/
public function withSetProviders(string ...$setProviders): self
{
foreach ($setProviders as $setProvider) {
if (\array_key_exists($setProvider, $this->setProviders)) {
continue;
}
if (!is_a($setProvider, SetProviderInterface::class, \true)) {
throw new InvalidConfigurationException(sprintf('Set provider "%s" must implement "%s"', $setProvider, SetProviderInterface::class));
}
$this->setProviders[$setProvider] = \true;
}
return $this;
}
/**
* @param PhpVersion::* $phpVersion
*/
private function addPhpLevelSets(int $phpVersion): self
{
$this->isWithPhpSetsUsed = \true;
$this->sets = array_merge($this->sets, \Rector\Configuration\PhpLevelSetResolver::resolveFromPhpVersion($phpVersion));
return $this;
}
private function reportDeprecatedPhpSetsMethod(string $methodName): self
{
SimpleParameterProvider::addParameter(\Rector\Configuration\Option::DEPRECATED_PHP_SETS_METHODS, $methodName);
return $this;View on GitHub (pinned to 408fcb0ff1)
Solutions
- Open the class named in the message and make it implement Rector\Set\SetProviderInterface with a sets() method returning Rector\Set\ValueObject\Set[] instances
- Fix the namespace/typo so the string matches the real provider class
- If you meant a built-in set, use withSets([SomeSetList::CONSTANT]) instead of withSetProviders()
- Pass class-strings via SomeProvider::class, never literals or objects
Example fix
// before
return $this->withSetProviders('App\Support\ProjectSetList');
// after
final class ProjectSetProvider implements \Rector\Set\SetProviderInterface
{
/**
* @return Set[]
*/
public function sets(): array
{
return [new Set('project-conventions', [SomeRule::class])];
}
}
return $this->withSetProviders(ProjectSetProvider::class); Defensive patterns
Strategy: type-guard
Type guard
/** @param class-string ...$providers */
function assertSetProviders(string ...$providers): void
{
foreach ($providers as $provider) {
if (! is_a($provider, \Rector\Set\SetProviderInterface::class, true)) {
throw new InvalidArgumentException(sprintf('%s does not implement SetProviderInterface', $provider));
}
}
} Try / catch
try {
$builder->withSetProviders(ProjectSetProvider::class);
} catch (InvalidConfigurationException $e) {
// message names the class and the interface; fix the class-string, not the call
$logger->error($e->getMessage());
} Prevention
- Always pass SomeProvider::class so the IDE resolves and refactors the symbol
- Keep one interface-ful provider per package and register it via composer extra or your bootstrap, not ad-hoc strings
- Run a static analyzer (PHPStan) with is-a checks so wrong class-strings fail in CI, not at runtime
When it happens
Trigger: Passing a FQCN that is not a SetProviderInterface implementation: a typo'd namespace, a plain value object, or a SetList constant instead of a provider class. Also triggered by passing a class that only extends a base class without implementing the interface.
Common situations: Copy-pasting a SetList:: constant into withSetProviders(); fat-fingered namespaces after renaming vendor packages; passing an instance or ::class of an unrelated helper while wiring custom sets.
Related errors
- "%s" rule is deprecated, as inverting nested ifs to early re
- "%s" rule is deprecated, as splitting a single condition int
- "%s" rule is deprecated, as splitting a single return into m
- "%s" is deprecated as risky change with little value. Use ma
- Bootstrap file "%s" does not exist.
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/3f462b5836c4e926.
Report an issue: GitHub.