{"record":{"id":"f2e735f2640aa43f","repo":"walkor/workerman","slug":"bad-worker-transport-var-export-this-transpor","errorCode":null,"errorMessage":"Bad worker->transport ${var_export($this->transport, true)}","messagePattern":"Bad worker->transport (.+?)","errorType":"exception","errorClass":"RuntimeException","httpStatus":null,"severity":"error","filePath":"src/Worker.php","lineNumber":2574,"sourceCode":"        // Get the application layer communication protocol and listening address.\n        [$scheme, $address] = explode(':', $this->socketName, 2);\n        // Check application layer protocol class.\n        if (!isset(self::BUILD_IN_TRANSPORTS[$scheme])) {\n            // Validate scheme contains only safe characters for class name resolution.\n            if (!preg_match('/^[a-zA-Z][a-zA-Z0-9]*$/', $scheme)) {\n                throw new RuntimeException(\"Invalid protocol scheme '$scheme'\");\n            }\n            $scheme = ucfirst($scheme);\n            $this->protocol = 'Protocols\\\\' . $scheme;\n            if (!class_exists($this->protocol)) {\n                $this->protocol = \"Workerman\\\\Protocols\\\\$scheme\";\n                if (!class_exists($this->protocol)) {\n                    throw new RuntimeException(\"class \\\\Protocols\\\\$scheme not exist\");\n                }\n            }\n\n            if (!isset(self::BUILD_IN_TRANSPORTS[$this->transport])) {\n                throw new RuntimeException('Bad worker->transport ' . var_export($this->transport, true));\n            }\n        } else if ($this->transport === 'tcp') {\n            $this->transport = $scheme;\n        }\n        //local socket\n        return self::BUILD_IN_TRANSPORTS[$this->transport] . \":\" . $address;\n    }\n\n    /**\n     * Pause accept new connections.\n     *\n     * @return void\n     */\n    public function pauseAccept(): void\n    {\n        if (static::$globalEvent !== null && !$this->pauseAccept && $this->mainSocket !== null) {\n            static::$globalEvent->offReadable($this->mainSocket);\n            $this->pauseAccept = true;","sourceCodeStart":2556,"sourceCodeEnd":2592,"githubUrl":"https://github.com/walkor/workerman/blob/1391112a61d23020e11e7b89f17050f6cfaea431/src/Worker.php#L2556-L2592","documentation":"When the socketName uses a non-builtin scheme (a custom protocol class), parseSocketAddress() also validates $worker->transport against Worker::BUILD_IN_TRANSPORTS = ['tcp','udp','unix','ssl']. An unknown transport value throws this exception with the var_export'd value, because the transport decides which low-level socket gets created (BUILD_IN_TRANSPORTS[$this->transport] . ':' . $address would otherwise index a missing key).","triggerScenarios":"Setting $worker->transport to anything outside tcp/udp/unix/ssl while using a custom scheme — e.g. $worker->transport = 'websocket' (not a transport; the scheme 'ws://' handles that), 'tcp6', 'http', 'Text', or null/int from a config variable.","commonSituations":"Confusing the application-layer protocol with the transport: writing transport='websocket' or 'http' instead of using the ws:// or http:// scheme in the listen address; loading transport from an env/config file with a typo or wrong casing; upgrading old configs that used arbitrary strings.","solutions":["Set the transport to a legal value: `$worker->transport = 'tcp';` (use 'udp', 'unix', or 'ssl' as appropriate).","If you wanted websocket/http, drop the custom transport and put it in the listen address instead: `new Worker('ws://0.0.0.0:8080')` or `new Worker('http://0.0.0.0:8080')`.","For TLS with a custom text protocol, keep transport='ssl' and configure $worker->transport context with local_cert/local_pk.","If the transport comes from config, validate/case-normalize it before assigning."],"exampleFix":"// before: 'websocket' is not a transport\n$worker = new Worker('myProto://0.0.0.0:8080');\n$worker->transport = 'websocket';\n\n// after: keep the transport low-level; express the protocol in the scheme\n$worker = new Worker('MyProto://0.0.0.0:8080');\n$worker->transport = 'tcp';","handlingStrategy":"validation","validationCode":"$transport = strtolower((string)$config['transport']);\nif (!in_array($transport, array_keys(Workerman\\Worker::BUILD_IN_TRANSPORTS), true)) {\n    throw new InvalidArgumentException(\n        \"transport must be one of tcp|udp|unix|ssl, got '{$config['transport']}'\"\n    );\n}\n$worker->transport = $transport;","typeGuard":"function isBuiltinTransport(string $transport): bool\n{\n    return isset(Workerman\\Worker::BUILD_IN_TRANSPORTS[$transport]);\n}","tryCatchPattern":null,"preventionTips":["Remember transport is only tcp/udp/unix/ssl; protocols like websocket/http belong in the listen scheme (ws://, http://).","Validate any transport value coming from env/config before assigning it to the worker."],"tags":["workerman","transport","config-validation","socket","php"],"backgroundTag":"invalid-config-value","analyzedSha":"1391112a61d23020e11e7b89f17050f6cfaea431","analyzedAt":"2026-08-21T02:05:46.744Z","schemaVersion":2},"datasetVersion":"2026-08-21T03:17:12.404Z"}