sebastianbergmann/phpunit · warning · PHPUnit\TextUI\XmlConfiguration\Exception

The file does not need to be migrated

Error message

The file does not need to be migrated

What it means

Migrator::migrate() throws this when the file already validates against the schema of the currently installed PHPUnit series AND its xsi:schemaLocation attribute is already current, so no migration step would change anything. It is PHPUnit's way of saying the command is a no-op, surfaced as an exception rather than a success message.

Source

Thrown at src/TextUI/Configuration/Xml/Migration/Migrator.php:44

{
    /**
     * @throws Exception
     * @throws MigrationException
     * @throws XmlException
     */
    public function migrate(string $filename): string
    {
        $origin = (new SchemaDetector)->detect($filename);

        if (!$origin->detected()) {
            throw new Exception('The file does not validate against any known schema');
        }

        $configurationDocument = (new XmlLoader)->loadFile($filename);

        if ($origin->version() === Version::series()) {
            if (!$this->schemaLocationNeedsUpdate($configurationDocument)) {
                throw new Exception('The file does not need to be migrated');
            }

            (new UpdateSchemaLocation)->migrate($configurationDocument);
        } else {
            foreach ((new MigrationBuilder)->build($origin->version()) as $migration) {
                $migration->migrate($configurationDocument);
            }
        }

        $configurationDocument->formatOutput       = true;
        $configurationDocument->preserveWhiteSpace = false;

        $xml = $configurationDocument->saveXML();

        assert($xml !== false);

        return $xml;
    }

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Treat it as confirmation that the configuration is already current — nothing to fix
  2. Remove or make the CI migration step conditional (only when the config predates the installed series)
  3. In automation, catch this specific exception and continue with exit code 0

Example fix

# before (CI fails on no-op migration)
vendor/bin/phpunit --migrate-configuration

# after (script tolerates 'nothing to do')
vendor/bin/phpunit --migrate-configuration || echo 'Configuration already current'
Defensive patterns

Strategy: fallback

Validate before calling

// Skip migration when the config already matches the installed series
$result = (new \PHPUnit\TextUI\XmlConfiguration\SchemaDetector)->detect('phpunit.xml');

$alreadyCurrent = $result->detected()
    && $result->version() === \PHPUnit\Runner\Version::series();

if (!$alreadyCurrent) {
    system('vendor/bin/phpunit --migrate-configuration');
} else {
    echo 'phpunit.xml already current, skipping migration' . PHP_EOL;
}

Try / catch

try {
    (new \PHPUnit\TextUI\XmlConfiguration\Migration\Migrator)->migrate($file);
} catch (\PHPUnit\TextUI\XmlConfiguration\Exception $e) {
    if (str_contains($e->getMessage(), 'does not need to be migrated')) {
        // intended state: treat as success and continue the pipeline
        return 0;
    }
    throw $e;
}

Prevention

When it happens

Trigger: Running `vendor/bin/phpunit --migrate-configuration` on a configuration that was already migrated in a previous run; CI pipelines that unconditionally run the migration step on every build even after the config was committed in current form.

Common situations: A migration step left in CI after the upgrade project finished; developers re-running the command 'just to be sure' after updating PHPUnit within the same major series.

Related errors


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