HKUDS/Vibe-Trading · error · RuntimeError

Not connected to signal-cli daemon

Error message

Not connected to signal-cli daemon

What it means

A JSON-RPC request was attempted via _send_http_request before the HTTP client existed, i.e. the channel is not started or start() failed.

Source

Thrown at agent/src/channels/signal.py:1424

        self, method: str, params: dict[str, Any] | None = None
    ) -> dict[str, Any]:
        """Send a JSON-RPC request via HTTP and wait for response."""
        # Generate request ID
        self._request_id += 1
        request_id = self._request_id

        # Build JSON-RPC request
        request = {"jsonrpc": "2.0", "method": method, "id": request_id}

        if params:
            request["params"] = params

        return await self._send_http_request(request)

    async def _send_http_request(self, request: dict[str, Any]) -> dict[str, Any]:
        """Send JSON-RPC request via HTTP."""
        if not self._http:
            raise RuntimeError("Not connected to signal-cli daemon")

        try:
            response = await self._http.post("/api/v1/rpc", json=request)
            response.raise_for_status()
            return response.json()
        except Exception as e:
            self.logger.error("HTTP request failed: {}", e)
            return {"error": {"message": str(e)}}

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Await start() (and confirm it succeeded) before any send
  2. Guard with the channel's running/connected state if exposed
  3. Don't reuse a channel instance after stop()

Example fix

# before
await channel.send(...)  # before start
# after
await channel.start()
await channel.send(...)
Defensive patterns

Strategy: validation

Validate before calling

if not getattr(channel, '_http', None):
    await channel.start()

Type guard

def is_started(ch) -> bool:
    return getattr(ch, '_http', None) is not None and ch._running

Try / catch

except RuntimeError as e:
    if 'Not connected' in str(e):
        await channel.start(); retry_send()

Prevention

When it happens

Trigger: Calling send() or typing-indicator methods before awaiting start(), or after stop() has torn down the client.

Common situations: Forgetting to await channel.start(), racing startup, or using the channel after an exception in start().

Related errors


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