{"record":{"id":"eb84a92feddd9919","repo":"sebastianbergmann/phpunit","slug":"subscriber-s-does-not-implement-a-known-interfa","errorCode":null,"errorMessage":"Subscriber \"%s\" does not implement a known interface","messagePattern":"Subscriber \"(.+?)\" does not implement a known interface","errorType":"exception","errorClass":"MapError","httpStatus":null,"severity":"error","filePath":"src/Event/TypeMap.php","lineNumber":81,"sourceCode":"    public function isKnownEventType(Event $event): bool\n    {\n        return in_array($event::class, $this->mapping, true);\n    }\n\n    /**\n     * @throws MapError\n     *\n     * @return class-string\n     */\n    public function map(Subscriber $subscriber): string\n    {\n        foreach (class_implements($subscriber) as $interface) {\n            if (array_key_exists($interface, $this->mapping)) {\n                return $this->mapping[$interface];\n            }\n        }\n\n        throw new MapError(\n            sprintf(\n                'Subscriber \"%s\" does not implement a known interface',\n                $subscriber::class,\n            ),\n        );\n    }\n\n    /**\n     * @param class-string $subscriberInterface\n     *\n     * @throws UnknownSubscriberException\n     */\n    private function ensureSubscriberInterfaceExists(string $subscriberInterface): void\n    {\n        if (!interface_exists($subscriberInterface)) {\n            throw new UnknownSubscriberException(\n                sprintf(\n                    'Subscriber \"%s\" does not exist or is not an interface',","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/sebastianbergmann/phpunit/blob/f123cdb2a2d49f15025794166cfed8bda8627dd2/src/Event/TypeMap.php#L63-L99","documentation":"TypeMap::map(Subscriber) resolves which event class a subscriber should be attached to by walking class_implements($subscriber) and returning the first interface present in the mapping array. MapError is thrown when no implemented interface is mapped. DirectDispatcher::registerSubscriber() calls isKnownSubscriberType() first, so that path normally raises UnknownSubscriberTypeException instead; MapError surfaces when map() is invoked directly without that guard.","triggerScenarios":"Calling $typeMap->map($subscriber) on a TypeMap containing no mapping for any interface the subscriber implements; registering a subscriber against a freshly constructed empty TypeMap; calling map() for a custom subscriber interface whose addMapping() was skipped or failed.","commonSituations":"Building custom dispatchers or runners on top of PHPUnit's Event component; unit tests exercising the Event subsystem directly; refactors that move subscribers between namespaces so their interfaces no longer match the registered keys.","solutions":["Call $typeMap->isKnownSubscriberType($subscriber) before map() and handle the false branch (skip, or register the missing mapping).","Add the missing mapping with $typeMap->addMapping(MySubscriberInterface::class, MyEvent::class) before calling map().","Prefer the built-in subscriber interfaces, which the Facade's default TypeMap already contains."],"exampleFix":"// before\n$eventClass = $typeMap->map($subscriber); // MapError when nothing is mapped\n\n// after\nif (!$typeMap->isKnownSubscriberType($subscriber)) {\n    $typeMap->addMapping(MySubscriberInterface::class, MyEvent::class);\n}\n$eventClass = $typeMap->map($subscriber);","handlingStrategy":"validation","validationCode":"if (!$typeMap->isKnownSubscriberType($subscriber)) {\n    $typeMap->addMapping(MySubscriberInterface::class, MyEvent::class);\n}\n\n$eventClass = $typeMap->map($subscriber); // safe now","typeGuard":null,"tryCatchPattern":"try {\n    $eventClass = $typeMap->map($subscriber);\n} catch (PHPUnit\\Event\\MapError $e) {\n    // No mapping for any implemented interface: register one or skip this subscriber\n}","preventionTips":["Treat isKnownSubscriberType() as the mandatory precondition of map().","Keep custom mappings in one bootstrap location so a TypeMap is never used half-configured.","Prefer built-in subscriber interfaces; the Facade's default map already contains them."],"tags":["phpunit","type-map","subscriber","event-system","php"],"backgroundTag":"unknown-subscriber-type","analyzedSha":"f123cdb2a2d49f15025794166cfed8bda8627dd2","analyzedAt":"2026-08-23T01:20:58.058Z","schemaVersion":2},"datasetVersion":"2026-08-23T08:06:27.607Z"}