rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as matching sensitive parameters by
Error message
"%s" rule is deprecated, as matching sensitive parameters by name is vague and risky. Add the #[\SensitiveParameter] attribute per case instead
What it means
Rector\Php82\Rector\Param\AddSensitiveParameterAttributeRector is deprecated: refactor() unconditionally throws Rector\Exception\ShouldNotHappenException on the first Param node it visits. The rule used to add the #[\SensitiveParameter] attribute to parameters matched by configured names (e.g. 'password'), but matching secrets by name alone is vague and risky - it can flag unrelated parameters that happen to share a name. Its configure() body is now an empty no-op, so any old configuration passed via withConfiguredRule() is silently discarded before the exception is thrown.
Source
Thrown at rules/Php82/Rector/Param/AddSensitiveParameterAttributeRector.php:41
* @var string
*/
public const SENSITIVE_PARAMETERS = 'sensitive_parameters';
/**
* @param array<string, mixed> $configuration
*/
public function configure(array $configuration): void
{
}
public function getNodeTypes(): array
{
return [Param::class];
}
/**
* @param Node\Param $node
*/
public function refactor(Node $node): ?Param
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as matching sensitive parameters by name is vague and risky. Add the #[\SensitiveParameter] attribute per case instead', self::class));
}
public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition('Add SensitiveParameter attribute to method and function configured parameters', [new ConfiguredCodeSample(<<<'CODE_SAMPLE'
class SomeClass
{
public function run(string $password)
{
}
}
CODE_SAMPLE
, <<<'CODE_SAMPLE'
class SomeClass
{
public function run(#[\SensitiveParameter] string $password)
{
}
}View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove AddSensitiveParameterAttributeRector from rector.php - it no longer adds anything.
- Add #[\SensitiveParameter] by hand to each parameter that genuinely carries a secret (token, password, private key), reviewing each call site.
- If you have many occurrences, write a small custom rule scoped to the exact services/parameters that handle secrets.
- Temporary stopgap only: pin the last rector version shipping the working rule, and schedule config cleanup.
Example fix
// before (rector.php)
->withConfiguredRule(AddSensitiveParameterAttributeRector::class, [
'password', 'secret',
])
// after (rector.php) - entry deleted
// before (src/Auth.php) // after (src/Auth.php)
public function login(string $password) public function login(#[\SensitiveParameter] string $password) Defensive patterns
Strategy: validation
Validate before calling
use Rector\Php82\Rector\Param\AddSensitiveParameterAttributeRector;
$rules = [/* your list */ AddSensitiveParameterAttributeRector::class];
if (in_array(AddSensitiveParameterAttributeRector::class, $rules, true)) {
throw new InvalidArgumentException('AddSensitiveParameterAttributeRector is deprecated; add #[\SensitiveParameter] manually instead');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'AddSensitiveParameterAttributeRector')) {
fwrite(STDERR, 'Remove the deprecated rule from rector.php and mark secrets manually.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Do not pass old parameter-name configuration to this rule - configure() is a no-op and the values are ignored.
- Handle secrets explicitly: add #[\SensitiveParameter] during code review of auth/crypto code.
- Audit rector.php after each upgrade for rules whose configure() became empty no-ops.
- Keep security-related migrations manual so each call site is consciously reviewed.
When it happens
Trigger: The rule is still referenced in rector.php (withRules() or withConfiguredRule() with the old parameter-name list) and rector processes any function/method parameter; refactor() throws on the first Param node regardless of configuration.
Common situations: Upgrading rector after this PHP 8.2 rule was gutted; security-check CI configs copied from older blog posts that still list the rule; assuming the old 'password'/'secret' name configuration still works because no config error is reported at load time.
Related errors
- "%s" rule is deprecated, as turning a docblock type into a r
- "%s" rule is deprecated, as risky. The "??" and "?:" operato
- "%s" is deprecated as depends on context and personal prefer
- "%s" rule is deprecated, as it is a personal preference that
- "%s" is deprecated, as simplifying regex ranges is a persona
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/5c2003a641abe1bc.
Report an issue: GitHub.