{"record":{"id":"41d653e34a220e1e","repo":"walkor/workerman","slug":"s-eventloopclass-must-implement-s","errorCode":null,"errorMessage":"%s::$eventLoopClass must implement %s","messagePattern":"(.+?)::\\$eventLoopClass must implement (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Worker.php","lineNumber":800,"sourceCode":"        restore_error_handler();\n    }\n\n    /**\n     * Init global event.\n     *\n     * @return void\n     */\n    protected static function initGlobalEvent(): void\n    {\n        if (static::$globalEvent !== null) {\n            static::$eventLoopClass = get_class(static::$globalEvent);\n            static::$globalEvent = null;\n            return;\n        }\n\n        if (!empty(static::$eventLoopClass)) {\n            if (!is_subclass_of(static::$eventLoopClass, EventInterface::class)) {\n                throw new RuntimeException(sprintf('%s::$eventLoopClass must implement %s', static::class, EventInterface::class));\n            }\n            return;\n        }\n\n        static::$eventLoopClass = match (true) {\n            extension_loaded('event') => Event::class,\n            default => Select::class,\n        };\n    }\n\n    /**\n     * Lock.\n     *\n     * @param int $flag\n     * @return void\n     */\n    protected static function lock(int $flag = LOCK_EX): void\n    {","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Worker.php#L782-L818","documentation":"Before the master process creates its event loop, Worker::initGlobalEvent() validates the configured Worker::$eventLoopClass and requires it to implement Workerman\\Events\\EventInterface (add/del/loop/onError/repeat/delay/...). Any other class - even a working event loop from another ecosystem - is rejected because Workerman drives it through that interface.","triggerScenarios":"Worker::$eventLoopClass = React\\EventLoop\\StreamSelectLoop::class or an Amp loop (no EventInterface); a typo in a configured class name that resolves to an unrelated class; a custom loop wrapper that forgot to implement the interface; config pulled from env applied without validation.","commonSituations":"Trying to share an existing ReactPHP/Swoole-style loop with Workerman; upgrading Workerman major versions where EventInterface changed; custom event-loop wrappers maintained in app code that drifted from the interface.","solutions":["Use one of Workerman's own loops, e.g. Workerman\\Events\\Event (ext-event), Workerman\\Events\\Select, or the Fiber/Ev implementations shipped in src/Events","If you must wrap a foreign loop, implement Workerman\\Events\\EventInterface on the wrapper (add, del, repeat, delay, deleteAllTimer, run, stop, onError, ...)","Fix the typo in the class name or unset Worker::$eventLoopClass to fall back to the automatic selection (ext-event if present, else Select)"],"exampleFix":"// before\nWorker::$eventLoopClass = React\\EventLoop\\StreamSelectLoop::class;\nWorker::runAll(); // throws '$eventLoopClass must implement Workerman\\Events\\EventInterface'\n\n// after\nWorker::$eventLoopClass = Workerman\\Events\\Event::class; // or omit for auto-select\nWorker::runAll();","handlingStrategy":"validation","validationCode":"$loopClass = $config['eventLoopClass'] ?? Workerman\\Events\\Select::class;\nif (!is_subclass_of($loopClass, Workerman\\Events\\EventInterface::class)) {\n    throw new InvalidArgumentException(\"$loopClass does not implement EventInterface\");\n}\nWorker::$eventLoopClass = $loopClass;","typeGuard":"function isValidLoopClass(string $class): bool\n{\n    return is_subclass_of($class, Workerman\\Events\\EventInterface::class);\n}","tryCatchPattern":null,"preventionTips":["Only assign loop classes from Workerman\\Events\\* unless you wrote an EventInterface adapter yourself","Add a boot-time assertion for the configured loop class so misconfigurations fail before forking"],"tags":["php","workerman","event-loop","configuration","interface-validation"],"backgroundTag":"event-loop-class-invalid","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}