rectorphp/rector · error · ShouldNotHappenException
"%s" rule is deprecated, as the scalar value target is too w
Error message
"%s" rule is deprecated, as the scalar value target is too wide and replaces values in unrelated contexts; use a custom rule scoped to the exact context instead
What it means
Rector\Transform\Rector\Scalar\ScalarValueToConstFetchRector is deprecated: refactor() throws Rector\Exception\ShouldNotHappenException on the first String_, Float_ or Int_ literal. The rule replaced configured scalar values (e.g. the int 10 with SomeClass::FOOBAR_INT), but a bare literal target is too wide - the same number or string appears in unrelated contexts, so the rewrite corrupts unrelated code. configure() is an empty no-op, so old value mappings are ignored before the throw.
Source
Thrown at rules/Transform/Rector/Scalar/ScalarValueToConstFetchRector.php:46
return new RuleDefinition('Replaces Scalar values with a ConstFetch or ClassConstFetch', [new ConfiguredCodeSample(<<<'SAMPLE'
$var = 10;
SAMPLE
, <<<'SAMPLE'
$var = \SomeClass::FOOBAR_INT;
SAMPLE
, [new ScalarValueToConstFetch(new Int_(10), new ClassConstFetch(new FullyQualified('SomeClass'), new Identifier('FOOBAR_INT')))])]);
}
public function getNodeTypes(): array
{
return [String_::class, Float_::class, Int_::class];
}
/**
* @param String_|Float_|Int_ $node
* @return \PhpParser\Node\Expr\ConstFetch|\PhpParser\Node\Expr\ClassConstFetch|null
*/
public function refactor(Node $node)
{
throw new ShouldNotHappenException(sprintf('"%s" rule is deprecated, as the scalar value target is too wide and replaces values in unrelated contexts; use a custom rule scoped to the exact context instead', self::class));
}
/**
* @param mixed[] $configuration
*/
public function configure(array $configuration): void
{
}
}
View on GitHub (pinned to 408fcb0ff1)
Solutions
- Remove ScalarValueToConstFetchRector from rector.php.
- Replace the meaningful literals manually with the intended class constant / const fetch, reviewing each context.
- If automation is needed, write a custom rule that matches the literal only in the exact contexts (specific methods/classes) where the constant applies.
Example fix
// before (rector.php)
->withConfiguredRule(ScalarValueToConstFetchRector::class, [
new ScalarValueToConstFetch(new Int_(10), new ClassConstFetch(new FullyQualified('SomeClass'), new Identifier('FOOBAR_INT'))),
])
// after (rector.php) - removed
// before // after
$limit = 10; $limit = SomeClass::FOOBAR_INT; Defensive patterns
Strategy: validation
Validate before calling
use Rector\Transform\Rector\Scalar\ScalarValueToConstFetchRector;
$rules = [/* your list */ ScalarValueToConstFetchRector::class];
if (in_array(ScalarValueToConstFetchRector::class, $rules, true)) {
throw new InvalidArgumentException('Rule deprecated; replace literals manually or with a context-scoped custom rule');
} Try / catch
try {
exit($rectorApplication->run());
} catch (\Rector\Exception\ShouldNotHappenException $e) {
if (str_contains($e->getMessage(), 'ScalarValueToConstFetchRector')) {
fwrite(STDERR, 'Remove the rule; bare-scalar matches hit unrelated contexts.' . PHP_EOL);
exit(1);
}
throw $e;
} Prevention
- Replace magic literals with constants in reviewed edits limited to the files that mean the constant.
- If automating, match on parent context (method/class), never on the bare literal - the reason this rule was dropped.
- Remember configure() is a no-op here: old ScalarValueToConstFetch mappings are ignored and cannot protect you.
When it happens
Trigger: The rule is still referenced in rector.php (withRules() or withConfiguredRule() with an old scalar=>const map, as in the rule's configured code sample) and rector visits any string/float/int literal; refactor() throws on the first literal.
Common situations: Configs that centralized 'magic numbers' via rector; rector upgrade breaking CI at the first literal encountered; users assuming their old value mapping still protects them because no config error appears.
Related errors
- "%s" rule is deprecated, as too niche; use a custom rule sco
- "%s" rule is deprecated, as a function call can rarely be tu
- "%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
AI-assisted analysis of rectorphp/rector@408fcb0ff1 (2026-08-21).
Data as JSON: /api/errors/2670be02cc7dad41.
Report an issue: GitHub.