{"record":{"id":"93c437ab86d4f9cd","repo":"HKUDS/Vibe-Trading","slug":"unix-socket-path-must-not-contain-nul-bytes","errorCode":null,"errorMessage":"unix_socket_path must not contain NUL bytes","messagePattern":"unix_socket_path must not contain NUL bytes","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"agent/src/channels/websocket.py","lineNumber":102,"sourceCode":"    streaming: bool = True\n    # Default 36 MB, upper 40 MB: supports up to 4 images at ~6 MB each after\n    # client-side Worker normalization (see webui Composer). 4 × 6 MB × 1.37\n    # (base64 overhead) + envelope framing stays under 36 MB; the 40 MB ceiling\n    # leaves a small margin for sender slop without opening a DoS avenue.\n    max_message_bytes: int = Field(default=37_748_736, ge=1024, le=41_943_040)\n    ping_interval_s: float = Field(default=20.0, ge=5.0, le=300.0)\n    ping_timeout_s: float = Field(default=20.0, ge=5.0, le=300.0)\n    ssl_certfile: str = \"\"\n    ssl_keyfile: str = \"\"\n\n    @field_validator(\"unix_socket_path\")\n    @classmethod\n    def unix_socket_path_format(cls, value: str) -> str:\n        value = value.strip()\n        if not value:\n            return \"\"\n        if \"\\x00\" in value:\n            raise ValueError(\"unix_socket_path must not contain NUL bytes\")\n        path = Path(value).expanduser()\n        if not path.is_absolute():\n            raise ValueError(\"unix_socket_path must be an absolute path\")\n        return str(path)\n\n    @field_validator(\"path\")\n    @classmethod\n    def path_must_start_with_slash(cls, value: str) -> str:\n        if not value.startswith(\"/\"):\n            raise ValueError('path must start with \"/\"')\n        return _normalize_config_path(value)\n\n    @field_validator(\"token_issue_path\")\n    @classmethod\n    def token_issue_path_format(cls, value: str) -> str:\n        value = value.strip()\n        if not value:\n            return \"\"","sourceCodeStart":84,"sourceCodeEnd":120,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/channels/websocket.py#L84-L120","documentation":"Raised by the WebSocketChannel config field validator for unix_socket_path when the supplied string contains a NUL byte (\\x00). Unix socket paths are passed to the OS bind() call, which uses NUL-terminated C strings, so embedded NULs would silently truncate the path. The validator rejects them up front.","triggerScenarios":"Setting unix_socket_path to a string with an embedded \\x00, e.g. from mis-decoded bytes, a truncated buffer, or string concatenation of binary data. value.strip() runs first, so only interior NULs trigger this.","commonSituations":"Reading the path from a binary config/protocol source that wasn't fully decoded to UTF-8; template rendering bugs that splice raw bytes; copy-pasting a path from terminal output containing control characters; fuzzed input reaching config parsing.","solutions":["Sanitize the input source: decode bytes with .decode('utf-8', errors='strict') and strip control characters before it reaches config","Log the repr(value) at the boundary to find where the NUL is being injected","Provide the path as a plain literal string in config (e.g. \"/run/app/ws.sock\")"],"exampleFix":"# before\nraw = socket.recv(108)  # may include trailing junk\ncfg = WebSocketConfig(unix_socket_path=raw.decode())\n# after\nraw = socket.recv(108)\ncfg = WebSocketConfig(unix_socket_path=raw.split(b\"\\x00\", 1)[0].decode(\"utf-8\"))","handlingStrategy":"validation","validationCode":"def clean_socket_path(raw: str | bytes) -> str:\n    if isinstance(raw, bytes):\n        raw = raw.split(b\"\\x00\", 1)[0].decode(\"utf-8\")\n    assert \"\\x00\" not in raw, \"socket path contains NUL\"\n    return raw.strip()\n\nunix_socket_path = clean_socket_path(config_source)","typeGuard":"def is_nul_free_path(s: str) -> bool:\n    return \"\\x00\" not in s","tryCatchPattern":null,"preventionTips":["Always fully decode bytes to UTF-8 before config assignment","Validate external inputs at the boundary (repr-inspect for control chars)","Prefer static string literals for socket paths in config files"],"tags":["websocket","unix-socket","config-validation","nul-byte"],"backgroundTag":"config-validation-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}