rector icon indicating copy to clipboard operation
rector copied to clipboard

symfony 7.3: InvokableCommandInputAttributeRector: System error: "Argument mode is required to be null or numeric"

Open shakaran opened this issue 8 months ago • 1 comments

# 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 avatar Jun 13 '25 20:06 shakaran

@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.

samsonasik avatar Jun 14 '25 02:06 samsonasik

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 avatar Jun 26 '25 18:06 gharlan

@gharlan feel free to provide fixture PR, thank you.

samsonasik avatar Jun 27 '25 02:06 samsonasik

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.

thats correct

shakaran avatar Jun 27 '25 10:06 shakaran

Please create failing fixture PR guys, otherwise, it won't fix by itself :)

samsonasik avatar Jun 27 '25 10:06 samsonasik

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).

gharlan avatar Jun 27 '25 10:06 gharlan

I am going to close it then, if you have a chance to create expected failing fixture, feel free to create PR :)

samsonasik avatar Jun 27 '25 10:06 samsonasik

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.

github-actions[bot] avatar Nov 28 '25 03:11 github-actions[bot]