HKUDS/Vibe-Trading · error · ValueError

unix_socket_path must not contain NUL bytes

Error message

unix_socket_path must not contain NUL bytes

What it means

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.

Source

Thrown at agent/src/channels/websocket.py:102

    streaming: bool = True
    # Default 36 MB, upper 40 MB: supports up to 4 images at ~6 MB each after
    # client-side Worker normalization (see webui Composer). 4 × 6 MB × 1.37
    # (base64 overhead) + envelope framing stays under 36 MB; the 40 MB ceiling
    # leaves a small margin for sender slop without opening a DoS avenue.
    max_message_bytes: int = Field(default=37_748_736, ge=1024, le=41_943_040)
    ping_interval_s: float = Field(default=20.0, ge=5.0, le=300.0)
    ping_timeout_s: float = Field(default=20.0, ge=5.0, le=300.0)
    ssl_certfile: str = ""
    ssl_keyfile: str = ""

    @field_validator("unix_socket_path")
    @classmethod
    def unix_socket_path_format(cls, value: str) -> str:
        value = value.strip()
        if not value:
            return ""
        if "\x00" in value:
            raise ValueError("unix_socket_path must not contain NUL bytes")
        path = Path(value).expanduser()
        if not path.is_absolute():
            raise ValueError("unix_socket_path must be an absolute path")
        return str(path)

    @field_validator("path")
    @classmethod
    def path_must_start_with_slash(cls, value: str) -> str:
        if not value.startswith("/"):
            raise ValueError('path must start with "/"')
        return _normalize_config_path(value)

    @field_validator("token_issue_path")
    @classmethod
    def token_issue_path_format(cls, value: str) -> str:
        value = value.strip()
        if not value:
            return ""

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Sanitize the input source: decode bytes with .decode('utf-8', errors='strict') and strip control characters before it reaches config
  2. Log the repr(value) at the boundary to find where the NUL is being injected
  3. Provide the path as a plain literal string in config (e.g. "/run/app/ws.sock")

Example fix

# before
raw = socket.recv(108)  # may include trailing junk
cfg = WebSocketConfig(unix_socket_path=raw.decode())
# after
raw = socket.recv(108)
cfg = WebSocketConfig(unix_socket_path=raw.split(b"\x00", 1)[0].decode("utf-8"))
Defensive patterns

Strategy: validation

Validate before calling

def clean_socket_path(raw: str | bytes) -> str:
    if isinstance(raw, bytes):
        raw = raw.split(b"\x00", 1)[0].decode("utf-8")
    assert "\x00" not in raw, "socket path contains NUL"
    return raw.strip()

unix_socket_path = clean_socket_path(config_source)

Type guard

def is_nul_free_path(s: str) -> bool:
    return "\x00" not in s

Prevention

When it happens

Trigger: 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.

Common situations: 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.

Understand the failure class

Background: Config validation failed: what "invalid value for {key}" and settings-rejection errors mean across 19 open-source libraries — this error's family across 19 libraries.

Related errors


AI-assisted analysis of HKUDS/Vibe-Trading@80ffdda44c (2026-08-28). Data as JSON: /api/errors/93c437ab86d4f9cd. Report an issue: GitHub.