sebastianbergmann/phpunit · error · PHPUnit\Util\Xml\XmlException

No supported schema was detected

Error message

No supported schema was detected

What it means

SchemaDetector::detect() returns either a successful or a failed SchemaDetectionResult. version() on the failed result unconditionally throws PHPUnit\Util\Xml\XmlException('No supported schema was detected') because a version simply does not exist for a failed detection. Calling it without first checking detected() is a programming error in the caller.

Source

Thrown at src/TextUI/Configuration/Xml/SchemaDetector/SchemaDetectionResult.php:36

 *
 * @immutable
 */
abstract readonly class SchemaDetectionResult
{
    /**
     * @phpstan-assert-if-true SuccessfulSchemaDetectionResult $this
     */
    public function detected(): bool
    {
        return false;
    }

    /**
     * @throws XmlException
     */
    public function version(): string
    {
        throw new XmlException('No supported schema was detected');
    }
}

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Always branch on the guard first: `$result = $detector->detect($file); if ($result->detected()) { $v = $result->version(); }`
  2. Handle the non-detected case explicitly (report 'unsupported configuration' to the user)
  3. Only as a last resort, catch PHPUnit\Util\Xml\XmlException around the version() call

Example fix

// before
$version = (new SchemaDetector)->detect($filename)->version(); // throws on failure

// after
$result = (new SchemaDetector)->detect($filename);

if (!$result->detected()) {
    throw new RuntimeException("{$filename} does not match any known PHPUnit schema");
}

$version = $result->version();
Defensive patterns

Strategy: type-guard

Type guard

$result = (new \PHPUnit\TextUI\XmlConfiguration\SchemaDetector)->detect($filename);

if (!$result->detected()) {
    // FailedSchemaDetectionResult: do NOT call version() on it
    throw new RuntimeException("{$filename} matches no supported schema");
}

// detected() === true implies a version is available
$version = $result->version();

Try / catch

try {
    $version = $result->version();
} catch (\PHPUnit\Util\Xml\XmlException $e) {
    // only reachable when detected() was false; fix the missing guard instead of catching
    $version = null;
}

Prevention

When it happens

Trigger: `(new SchemaDetector)->detect('phpunit.xml')->version()` chained without checking ->detected(); any custom tooling (IDE plugin, migration script, linter) built on SchemaDetector that reads version() unconditionally when the file matched no schema.

Common situations: Third-party tooling wrapping PHPUnit's schema detection; scripts that assumed detect() throws on failure instead of returning a result object.

Related errors


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