sebastianbergmann/phpunit · error · UnknownEventException

Event class "%s" does not exist

Error message

Event class "%s" does not exist

What it means

The second argument of TypeMap::addMapping() must be an existing class name; ensureEventClassExists() throws UnknownEventException when class_exists() fails (including its autoload attempt). It runs before the Event-interface check, so a missing class is reported distinctly from a class that exists but does not implement Event.

Source

Thrown at src/Event/TypeMap.php:114

        if (!interface_exists($subscriberInterface)) {
            throw new UnknownSubscriberException(
                sprintf(
                    'Subscriber "%s" does not exist or is not an interface',
                    $subscriberInterface,
                ),
            );
        }
    }

    /**
     * @param class-string $eventClass
     *
     * @throws UnknownEventException
     */
    private function ensureEventClassExists(string $eventClass): void
    {
        if (!class_exists($eventClass)) {
            throw new UnknownEventException(
                sprintf(
                    'Event class "%s" does not exist',
                    $eventClass,
                ),
            );
        }
    }

    /**
     * @param class-string $subscriberInterface
     *
     * @throws InvalidSubscriberException
     */
    private function ensureSubscriberInterfaceExtendsInterface(string $subscriberInterface): void
    {
        if (!in_array(Subscriber::class, class_implements($subscriberInterface), true)) {
            throw new InvalidSubscriberException(
                sprintf(

View on GitHub (pinned to f123cdb2a2)

Solutions

  1. Create the event class or fix the FQCN; prefer MyEvent::class over string literals so the IDE and PHP verify it.
  2. Verify with class_exists(MyEvent::class) in the same process/autoloader context if unsure.
  3. Run 'composer dump-autoload' (or install the missing package) and retry.

Example fix

// before
$typeMap->addMapping(MySubscriberInterface::class, 'App\Event\OrderPlaced'); // literal, class in App\Events\

// after
use App\Events\OrderPlaced;

$typeMap->addMapping(MySubscriberInterface::class, OrderPlaced::class);
Defensive patterns

Strategy: validation

Validate before calling

if (!class_exists($eventClass)) {
    throw new InvalidArgumentException($eventClass . ' does not exist; create the class or fix the FQCN');
}

$typeMap->addMapping($subscriberInterface, $eventClass);

Type guard

/** @phpstan-assert class-string $name */
function assertClassExists(string $name): void
{
    if (!class_exists($name)) {
        throw new InvalidArgumentException("Class '{$name}' does not exist");
    }
}

Prevention

When it happens

Trigger: addMapping(MySubscriberInterface::class, 'App\Event\ThingHappened') where ThingHappened is misspelled, not yet created, or defined in a package that is not installed; case mismatches in namespace segments on case-sensitive filesystems.

Common situations: Custom event development where the mapping is wired before the event class is written; refactors that rename event classes without updating registration code; partial vendor trees after a failed 'composer install'; stale opcache after moving files.

Related errors


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