symfony 7.3: InvokableCommandInputAttributeRector: System error: "Argument mode is required to be null or numeric"
# vendor/bin/rector --version
Rector 2.0.18
Rule affected: Rector\Symfony\Symfony73\Rector\Class_\InvokableCommandInputAttributeRector
vendor/bin/rector --debug
[info] Sets loaded based on installed packages:
* /srv/vendor/rector/rector/vendor/rector/rector-doctrine/config/sets/doctrine-bundle-23.php
* /srv/vendor/rector/rector/vendor/rector/rector-doctrine/config/sets/doctrine-bundle-28.php
* /srv/vendor/rector/rector/vendor/rector/rector-doctrine/config/sets/doctrine-dbal-40.php
* /srv/vendor/rector/rector/vendor/rector/rector-doctrine/config/sets/doctrine-dbal-42.php
* /srv/vendor/rector/rector/vendor/rector/rector-doctrine/config/sets/doctrine-orm-300.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony70/symfony70-dependency-injection.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony70/symfony70-serializer.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony70/symfony70-http-foundation.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony71/symfony71-dependency-injection.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony71/symfony71-serializer.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony72/symfony72-serializer.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony73/symfony73-console.php
* /srv/vendor/rector/rector/vendor/rector/rector-symfony/config/sets/symfony/symfony7/symfony73/symfony73-twig-bundle.php
* /srv/vendor/rector/rector/config/set/nette-utils/nette-utils4.php
Error:
[ERROR] Could not process "/src/Command/DownloadDocumentCommand.php" file, due to:
"System error: "Argument mode is required to be null or numeric"
Stack trace
Stack trace:
#0
vendor/rector/rector/vendor/rector/rector-symfony/rules/Symfony73/Rector/Class_/InvokableCommandInputAttributeR
ector.php(157):
Rector\Symfony\Symfony73\NodeAnalyzer\CommandArgumentsAndOptionsResolver->collectCommandArguments(Object(PhpPa
rser\Node\Stmt\ClassMethod))
#1 vendor/rector/rector/src/Rector/AbstractRector.php(112):
Rector\Symfony\Symfony73\Rector\Class_\InvokableCommandInputAttributeRector->refactor(Object(PhpParser\Node\St
mt\Class_))
#2 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(173):
Rector\Rector\AbstractRector->enterNode(Object(PhpParser\Node\Stmt\Class_))
#3 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(90):
PhpParser\NodeTraverser->traverseArray(Array)
#4 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(200):
PhpParser\NodeTraverser->traverseNode(Object(PhpParser\Node\Stmt\Namespace_))
#5 vendor/rector/rector/vendor/nikic/php-parser/lib/PhpParser/NodeTraverser.php(71):
PhpParser\NodeTraverser->traverseArray(Array)
#6 vendor/rector/rector/src/PhpParser/NodeTraverser/RectorNodeTraverser.php(49):
PhpParser\NodeTraverser->traverse(Array)
#7 vendor/rector/rector/src/Application/FileProcessor.php(95):
Rector\PhpParser\NodeTraverser\RectorNodeTraverser->traverse(Array)
#8 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(174):
Rector\Application\FileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#9 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(151):
Rector\Application\ApplicationFileProcessor->processFile(Object(Rector\ValueObject\Application\File),
Object(Rector\ValueObject\Configuration))
#10 vendor/rector/rector/src/Application/ApplicationFileProcessor.php(128):
Rector\Application\ApplicationFileProcessor->processFiles(Array, Object(Rector\ValueObject\Configuration),
Object(Closure), Object(Closure))
#11 vendor/rector/rector/src/Console/Command/ProcessCommand.php(172):
Rector\Application\ApplicationFileProcessor->run(Object(Rector\ValueObject\Configuration),
Object(RectorPrefix202506\Symfony\Component\Console\Input\ArgvInput))
#12 vendor/rector/rector/vendor/symfony/console/Command/Command.php(285):
Rector\Console\Command\ProcessCommand->execute(Object(RectorPrefix202506\Symfony\Component\Console\Input\ArgvI
nput), Object(RectorPrefix202506\Symfony\Component\Console\Output\ConsoleOutput))
#13 vendor/rector/rector/vendor/symfony/console/Application.php(900):
RectorPrefix202506\Symfony\Component\Console\Command\Command->run(Object(RectorPrefix202506\Symfony\Component\
Console\Input\ArgvInput), Object(RectorPrefix202506\Symfony\Component\Console\Output\ConsoleOutput))
#14 vendor/rector/rector/vendor/symfony/console/Application.php(279):
RectorPrefix202506\Symfony\Component\Console\Application->doRunCommand(Object(Rector\Console\Command\ProcessCo
mmand), Object(RectorPrefix202506\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202506\Symfony\Component\Console\Output\ConsoleOutput))
#15 vendor/rector/rector/src/Console/ConsoleApplication.php(63):
RectorPrefix202506\Symfony\Component\Console\Application->doRun(Object(RectorPrefix202506\Symfony\Component\Co
nsole\Input\ArgvInput), Object(RectorPrefix202506\Symfony\Component\Console\Output\ConsoleOutput))
#16 vendor/rector/rector/vendor/symfony/console/Application.php(162):
Rector\Console\ConsoleApplication->doRun(Object(RectorPrefix202506\Symfony\Component\Console\Input\ArgvInput),
Object(RectorPrefix202506\Symfony\Component\Console\Output\ConsoleOutput))
#17 vendor/rector/rector/bin/rector.php(130): RectorPrefix202506\Symfony\Component\Console\Application->run()
#18 vendor/rector/rector/bin/rector(5): require_once('vendor/rec...')
#19 vendor/bin/rector(119): include('vendor/rec...')
#20 {main}". On line: 50
Code:
<?php
declare(strict_types=1);
namespace App\Command;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\{InputInterface, InputOption};
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
#[AsCommand(
name: 'download-document',
description: 'download document',
hidden: false,
)]
final class DownloadDocumentCommand extends Command
{
public function __construct(EntityManagerInterface $entityManager, public ContainerInterface $container)
{
parent::__construct();
}
protected function configure(): void
{
$this->addArgument('contractId', null, InputOption::VALUE_REQUIRED, 'contractId');
}
protected function execute(InputInterface $input, OutputInterface $output): int
{
return Command::SUCCESS;
}
}
Using the set SymfonySetList::SYMFONY_73 the affected rule seems:
Rector config file:
<?php
use Rector\Config\RectorConfig;
use Rector\Symfony\Set\SymfonySetList;
use Rector\Doctrine\Set\DoctrineSetList;
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector;
use Rector\DeadCode\Rector\Property\RemoveUnusedPrivatePropertyRector;
use Rector\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchExprVariableRector;
use Rector\Naming\Rector\Class_\RenamePropertyToMatchTypeRector;
use Rector\Naming\Rector\ClassMethod\RenameParamToMatchTypeRector;
use Rector\Naming\Rector\Assign\RenameVariableToMatchMethodCallReturnTypeRector;
use Rector\Naming\Rector\ClassMethod\RenameVariableToMatchNewTypeRector;
use Rector\Naming\Rector\Foreach_\RenameForeachValueVariableToMatchMethodCallReturnTypeRector;
return RectorConfig::configure()
->withComposerBased(
twig: true,
doctrine: true,
phpunit: true,
symfony: true,
netteUtils: true
)
->withAttributesSets(
symfony: true,
doctrine: true,
mongoDb: true,
gedmo: true,
phpunit: true,
fosRest: true,
jms: true,
sensiolabs: true,
behat: true
)
->withRootFiles()
->withFileExtensions(fileExtensions: ['php', 'phtml'])
->withParallel(
timeoutSeconds: 120,
maxNumberOfProcess: 4,
jobSize: 10
)
->withSkip(skip: [
TypedPropertyFromCreateMockAssignRector::class,
RemoveUnusedPrivatePropertyRector::class,
RenameForeachValueVariableToMatchExprVariableRector::class,
RenamePropertyToMatchTypeRector::class,
RenameParamToMatchTypeRector::class,
RenameVariableToMatchMethodCallReturnTypeRector::class,
RenameVariableToMatchNewTypeRector::class,
RenameForeachValueVariableToMatchMethodCallReturnTypeRector::class,
])
->withPaths(
paths: [
__DIR__ . '/src',
]
)
->withImportNames(
importNames: true,
importDocBlockNames: false,
importShortClasses: true,
removeUnusedImports: true
)
->withPreparedSets(
typeDeclarations: true,
privatization: true,
strictBooleans: true,
earlyReturn: true,
deadCode: true,
naming: true,
instanceOf: true,
codeQuality: true,
codingStyle: true,
doctrineCodeQuality: true,
phpunitCodeQuality: true,
symfonyCodeQuality: true,
rectorPreset: true,
symfonyConfigs: true
)
->withPhpSets(php84: true)
->withSets(sets: [
SymfonySetList::SYMFONY_73,
SymfonySetList::SYMFONY_CODE_QUALITY,
SymfonySetList::SYMFONY_CONSTRUCTOR_INJECTION,
DoctrineSetList::DOCTRINE_CODE_QUALITY
]);
My guess is that:
$this->addArgument('contractId', null, InputOption::VALUE_REQUIRED, 'contractId');
Should be:
$this->addArgument('contractId', InputOption::VALUE_REQUIRED, 'contractId');
And the extra param breaks the rule
https://symfony.com/blog/new-in-symfony-7-3-invokable-commands-and-input-attributes
https://symfony.com/doc/current/console/input.html#adding-argument-option-value-completion
@shakaran could you create fixture PR for it for input and expected output at https://github.com/rectorphp/rector-symfony/tree/1a199fc1af9885bb647b160a5be218f69f4e6338/rules-tests/Symfony73/Rector/Class_/InvokableCommandInputAttributeRector/Fixture ? Thank you.
My guess is that:
$this->addArgument('contractId', null, InputOption::VALUE_REQUIRED, 'contractId');
Should be:
$this->addArgument('contractId', InputOption::VALUE_REQUIRED, 'contractId');
Also replace InputOption::VALUE_REQUIRED by InputArgument::REQUIRED.
@gharlan feel free to provide fixture PR, thank you.
My guess is that: $this->addArgument('contractId', null, InputOption::VALUE_REQUIRED, 'contractId'); Should be: $this->addArgument('contractId', InputOption::VALUE_REQUIRED, 'contractId');
Also replace
InputOption::VALUE_REQUIREDbyInputArgument::REQUIRED.
thats correct
Please create failing fixture PR guys, otherwise, it won't fix by itself :)
I'm not sure if the rector code should be changed here. The given code is wrong, so it has to be fixed anyway (by the developer).
I am going to close it then, if you have a chance to create expected failing fixture, feel free to create PR :)
This issue has been automatically locked because it has been closed for 150 days. Please open a new issue if you have a similar problem.