Skip to content

Cannot use min validator with IntegerNode when passing env parameter #58878

Open
@revilon1991

Description

@revilon1991

Symfony version(s) affected

7.1.6

Description

If you are describing the configuration for your bundle, the bug will reproduce under the following conditions:

  • You use integerNode
  • You apply the min validator
  • You set the value in the config using an environment variable
// src/DependencyInjection/Configuration.php
class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder(): TreeBuilder
    {
        $treeBuilder = new TreeBuilder('acme_bundle');
        $rootNode = $treeBuilder->getRootNode();

        $rootNode
            ->children()
                ->integerNode('port')
                    ->min(1)
                ->end()
            ->end();

        return $treeBuilder;
    }
}
# config/packages/acme_bundle.yaml
acme_bundle:
    port: '%env(int:PORT)%'

When clearing the cache, we get the following error:

In NumericNode.php line 45:
                                                                                                                             
  The value 0 is too small for path "acme_bundle.port". Should be greater than or equal to 1

The issue lies in this method, Symfony\Component\Config\Definition\NumericNode::finalizeValue, which performs validation before the value is resolved.

How to reproduce

  1. Install Symfony
composer create-project symfony/skeleton my_project
cd my_project
  1. Create a New Bundle
mkdir -p src/AcmeBundle/DependencyInjection
  1. Define Configuration in the Bundle
// src/AcmeBundle/DependencyInjection/Configuration.php
namespace App\AcmeBundle\DependencyInjection;

use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;

class Configuration implements ConfigurationInterface
{
    public function getConfigTreeBuilder(): TreeBuilder
    {
        $treeBuilder = new TreeBuilder('acme_bundle');
        $rootNode = $treeBuilder->getRootNode();

        $rootNode
            ->children()
                ->integerNode('port')
                    ->min(1)
                ->end()
            ->end();

        return $treeBuilder;
    }
}
  1. Register the Bundle
return [
    App\AcmeBundle\AcmeBundle::class => ['all' => true],
];
  1. Add the Configuration to the Bundle
// src/AcmeBundle/AcmeBundle.php
namespace App\AcmeBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class AcmeBundle extends Bundle
{
}
  1. Set Up Configuration in YAML
acme_bundle:
    port: '%env(int:PORT)%'
  1. Set an Environment Variable
PORT=8080
  1. Clear the Cache
php bin/console cache:clear
  1. Observe the Error
In NumericNode.php line 45:
                                                                                                                        
  The value 0 is too small for path "acme_bundle.port". Should be greater than or equal to 1

Possible Solution

Solution: Move the min validation to the DependencyInjection\AcmeExtension level.

// src/AcmeBundle/DependencyInjection/AcmeExtension.php
namespace App\AcmeBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;

class AcmeExtension extends Extension
{
    public function load(array $configs, ContainerBuilder $container)
    {
        $configuration = new Configuration();
        $config = $this->processConfiguration($configuration, $configs);

        // Manual validation for the 'port' configuration
        if ($config['port'] < 1) {
            throw new InvalidArgumentException('The "port" value must be greater than or equal to 1.');
        }

        $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
        $loader->load('services.yaml');
    }
}

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions