sebastianbergmann/phpunit · error · PHPUnit\Util\InvalidVersionOperatorException

"%s" is not a valid version_compare() operator

Error message

"%s" is not a valid version_compare() operator

What it means

VersionComparisonOperator is the value object PHPUnit uses for version constraints (for example the phpVersionOperator attribute on <directory>/<file> nodes in phpunit.xml testsuites, or operators parsed from metadata requirements like #[RequiresPhp('>= 8.1')]). ensureOperatorIsValid() only accepts operators version_compare() understands: <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne. Anything else throws InvalidVersionOperatorException.

Source

Thrown at src/Util/VersionComparisonOperator.php:54

    }

    /**
     * @return '!='|'<'|'<='|'<>'|'='|'=='|'>'|'>='|'eq'|'ge'|'gt'|'le'|'lt'|'ne'
     */
    public function asString(): string
    {
        return $this->operator;
    }

    /**
     * @param '!='|'<'|'<='|'<>'|'='|'=='|'>'|'>='|'eq'|'ge'|'gt'|'le'|'lt'|'ne' $operator
     *
     * @throws InvalidVersionOperatorException
     */
    private function ensureOperatorIsValid(string $operator): void
    {
        if (!in_array($operator, ['<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'], true)) {
            throw new InvalidVersionOperatorException($operator);
        }
    }
}

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Use one of the supported operators: '<', 'lt', '<=', 'le', '>', 'gt', '>=', 'ge', '==', '=', 'eq', '!=', '<>', 'ne'
  2. For '>= 8.1' style requirements you can usually omit the operator entirely — PHPUnit defaults to '>=' when none is given
  3. Remove composer-only operators such as ^ or ~; express them with explicit comparisons instead
  4. If validating user-supplied constraints, check against the allowed list before passing them in

Example fix

<!-- before -->
<testsuites>
  <directory suffix="Test.php" phpVersion="8.1" phpVersionOperator="=>">tests</directory>
</testsuites>

<!-- after -->
<testsuites>
  <directory suffix="Test.php" phpVersion="8.1" phpVersionOperator="&gt;=">tests</directory>
</testsuites>
Defensive patterns

Strategy: type-guard

Validate before calling

$operator = $node->getAttribute('phpVersionOperator');
$allowed = ['<','lt','<=','le','>','gt','>=','ge','==','=','eq','!=','<>','ne'];
if (!in_array($operator, $allowed, true)) {
    throw new InvalidArgumentException("Unsupported operator '{$operator}'");
}

Type guard

/** @param string $operator @phpstan-assert-if-true ='<'|'lt'|'<='|'le'|'>'|'gt'|'>='|'ge'|'=='|'='|'eq'|'!='|'<>'|'ne' */
static function isValidVersionOperator(string $operator): bool
{
    return in_array($operator, ['<','lt','<=','le','>','gt','>=','ge','==','=','eq','!=','<>','ne'], true);
}

Try / catch

use PHPUnit\Util\InvalidVersionOperatorException;

try {
    $op = new VersionComparisonOperator($candidate);
} catch (InvalidVersionOperatorException $e) {
    // fall back to the default operator instead of failing the run
    $op = new VersionComparisonOperator('>=');
}

Prevention

When it happens

Trigger: Setting phpVersionOperator to an unsupported string on a <directory> or <file> node in phpunit.xml (e.g. '=>', '~', '===', 'gte'), or constructing VersionComparisonOperator directly with such a value.

Common situations: Assuming composer-style constraint syntax (^, ~) works in phpunit.xml; typos like '=<'; copying version logic from another tool's config into the testsuite attributes.

Related errors


AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23). Data as JSON: /api/errors/50724d5a32335a5e. Report an issue: GitHub.