sebastianbergmann/phpunit · error · CodeCoverageDriverException
Configured code coverage driver class "%s" does not extend %
Error message
Configured code coverage driver class "%s" does not extend %s
What it means
The class named in the <coverage driver="..."> attribute exists, but is_subclass_of() showed it is not a subclass of SebastianBergmann\CodeCoverage\Driver\Driver — the contract PHPUnit's coverage subsystem drives. Only Driver subclasses can be instantiated, so activation aborts with this error.
Source
Thrown at src/Runner/CodeCoverage.php:618
}
/**
* @phpstan-ignore return.internalClass
*/
private function instantiateDriver(string $driverClass, Filter $filter, Granularity $granularity): Driver
{
if (!class_exists($driverClass)) {
throw new CodeCoverageDriverException(
sprintf(
'Configured code coverage driver class "%s" does not exist',
$driverClass,
),
);
}
/** @phpstan-ignore classConstant.internalClass */
if (!is_subclass_of($driverClass, Driver::class)) {
throw new CodeCoverageDriverException(
sprintf(
'Configured code coverage driver class "%s" does not extend %s',
$driverClass,
/** @phpstan-ignore classConstant.internalClass */
Driver::class,
),
);
}
$reflection = new ReflectionClass($driverClass);
if (!$reflection->isInstantiable()) {
throw new CodeCoverageDriverException(
sprintf(
'Configured code coverage driver class "%s" is not instantiable',
$driverClass,
),
);View on GitHub (pinned to f123cdb2a2)
Solutions
- Make the class extend SebastianBergmann\CodeCoverage\Driver\Driver and implement its abstract methods.
- Align the php-code-coverage version with what this PHPUnit build expects (composer why-not phpunit/phpunit, then update).
- If the custom driver is not maintained, drop the driver attribute and use the built-in driver selector.
Example fix
// before
class MyDriver
{
public function start(): void {}
public function stop(): array { return []; }
}
// after
class MyDriver extends \SebastianBergmann\CodeCoverage\Driver\Driver
{
// implement the abstract methods of the Driver base class
} Defensive patterns
Strategy: type-guard
Type guard
function isUsableCoverageDriver(string $class): bool
{
return class_exists($class)
&& is_subclass_of($class, \SebastianBergmann\CodeCoverage\Driver\Driver::class);
} Prevention
- Extend SebastianBergmann\CodeCoverage\Driver\Driver when writing custom drivers, and re-verify after php-code-coverage upgrades.
- Lock php-code-coverage to the version your PHPUnit build requires (composer why-not).
- Add a CI check asserting is_subclass_of($driverClass, Driver::class) for the configured driver.
When it happens
Trigger: driver pointing at a class implementing an older php-code-coverage driver interface (version skew after upgrading php-code-coverage), a plain class with a similarly named API, or a wrapper around Xdebug/PCOV functions that never extended Driver.
Common situations: Upgrading PHPUnit/php-code-coverage while keeping a custom driver built against the old API; drivers copied from another project; implementing a same-shaped interface instead of extending the Driver base class.
Related errors
- Configured code coverage driver class "%s" does not exist
- Configured code coverage driver class "%s" is not instantiab
- Cannot read baseline %s, file does not exist
- Subscriber "%s" does not implement any known interface - did
- Unknown event type "%s"
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/536969566df91107.
Report an issue: GitHub.