sebastianbergmann/phpunit · error · UnknownEventTypeException
Unknown event type "%s"
Error message
Unknown event type "%s"
What it means
DirectDispatcher::dispatch() only delivers events whose concrete class is a value in the dispatcher's TypeMap (isKnownEventType() performs in_array($event::class, $mapping, true)). All built-in event classes are seeded by Facade::registerDefaultTypes(); a custom event class with no registered subscriber-interface mapping is rejected before any tracer or subscriber sees it. The check preserves the invariant that every dispatched event is routable.
Source
Thrown at src/Event/Dispatcher/DirectDispatcher.php:81
$eventClassName = $this->typeMap->map($subscriber);
if (!array_key_exists($eventClassName, $this->subscribers)) {
$this->subscribers[$eventClassName] = [];
}
$this->subscribers[$eventClassName][] = $subscriber;
}
/**
* @throws Throwable
* @throws UnknownEventTypeException
*/
public function dispatch(Event $event): void
{
$eventClassName = $event::class;
if (!$this->typeMap->isKnownEventType($event)) {
throw new UnknownEventTypeException(
sprintf(
'Unknown event type "%s"',
$eventClassName,
),
);
}
foreach ($this->tracers as $tracer) {
try {
$tracer->trace($event);
// @codeCoverageIgnoreStart
} catch (Throwable $t) {
$this->handleThrowable($t);
}
// @codeCoverageIgnoreEnd
}
if (!array_key_exists($eventClassName, $this->subscribers)) {View on GitHub (pinned to f123cdb2a2)
Solutions
- Register the event before dispatching: $typeMap->addMapping(MyEventSubscriber::class, MyEvent::class), then dispatch MyEvent through the DirectDispatcher built with that same TypeMap.
- For built-in events, emit through Facade::emitter() (DispatchingEmitter) instead of calling dispatch() yourself, so the seeded TypeMap is used.
- Ensure registration and dispatch share one TypeMap instance; a map populated after the dispatcher is constructed still works (it is the same object), but a different map will not.
Example fix
// before $dispatcher = new DirectDispatcher(new TypeMap); // empty map $dispatcher->dispatch(new OrderPlaced($orderId)); // UnknownEventTypeException // after $typeMap = new TypeMap; $typeMap->addMapping(OrderPlacedSubscriber::class, OrderPlaced::class); $dispatcher = new DirectDispatcher($typeMap); $dispatcher->dispatch(new OrderPlaced($orderId));
Defensive patterns
Strategy: validation
Validate before calling
// TypeMap exposes a public predicate; use the same instance the dispatcher was built with
if (!$typeMap->isKnownEventType($event)) {
$typeMap->addMapping($event::class . 'Subscriber', $event::class); // or skip dispatching
}
$typeMap->dispatcher()->dispatch($event); Try / catch
try {
$dispatcher->dispatch($event);
} catch (PHPUnit\Event\UnknownEventTypeException $e) {
// Event class not mapped: register the mapping or drop the custom event
} Prevention
- Keep a single shared TypeMap for registration and dispatching so the mapping sets stay in sync.
- For built-in events, emit through Facade::emitter() instead of calling dispatch() directly.
- In custom runners, register every custom event's mapping during bootstrap, before the first dispatch.
When it happens
Trigger: Calling $dispatcher->dispatch(new MyCustomEvent(...)) with a class implementing PHPUnit\Event\Event that was never registered via TypeMap::addMapping(); constructing DirectDispatcher with 'new TypeMap' (empty map) instead of the Facade's seeded map; emitting an event class whose mapping was dropped during a refactor.
Common situations: Adding application-specific events in a custom runner built on PHPUnit's Event component; reusing the Event subsystem outside the phpunit binary and forgetting the default map is not auto-populated there; keeping dispatch code that hardcodes event class names across a PHPUnit upgrade that renamed them.
Related errors
- Subscriber "%s" does not implement any known interface - did
- Subscriber "%s" does not implement a known interface
- Subscriber "%s" does not exist or is not an interface
- Event class "%s" does not exist
- Subscriber "%s" does not extend Subscriber interface
AI-assisted analysis of sebastianbergmann/phpunit@f123cdb2a2 (2026-08-23).
Data as JSON: /api/errors/c6c369d3bdffe5eb.
Report an issue: GitHub.