HKUDS/Vibe-Trading · error · RuntimeError

HTTP client not initialized for Signal SSE stream

Error message

HTTP client not initialized for Signal SSE stream

What it means

Internal invariant error: the SSE receive loop was started before the httpx AsyncClient was created, indicating a lifecycle/state bug rather than an environment problem.

Source

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

                else:
                    self.logger.debug(
                        f"Signal message sent, timestamp: {response.get('result', {}).get('timestamp')}"
                    )

        except Exception:
            self.logger.exception("Error sending Signal message")
            raise
        finally:
            # Keep typing active across progress updates; stop on the final reply.
            if not is_progress_message:
                # Avoid immediate START->STOP for fast responses, which can be invisible
                # in some Signal clients. Let indicator expire naturally (~15s).
                await self._stop_typing(msg.chat_id, send_stop=False)

    async def _sse_receive_loop(self) -> None:
        """Receive messages via Server-Sent Events (HTTP mode)."""
        if not self._http:
            raise RuntimeError("HTTP client not initialized for Signal SSE stream")

        self.logger.info("Started Signal message receive loop (SSE)")

        try:
            async with self._http.stream("GET", "/api/v1/events") as response:
                if response.status_code != 200:
                    raise ConnectionError(
                        f"SSE connection failed with status {response.status_code}"
                    )

                self.logger.info("Subscribed to Signal messages via SSE")

                # Buffer for accumulating SSE data across multiple lines
                event_buffer = []

                async for line in response.aiter_lines():
                    if not self._running:
                        break

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Don't call _sse_receive_loop directly; use start()
  2. Check logs for earlier startup errors that prevented client init
  3. Report as a bug if it happens via normal start() flow
Defensive patterns

Strategy: type-guard

Validate before calling

assert channel._http is not None, 'channel not started'

Type guard

def is_signal_http_ready(ch) -> bool:
    return getattr(ch, '_http', None) is not None

Prevention

When it happens

Trigger: Calling _sse_receive_loop directly, or start() flow that skips HTTP client initialization (misconfigured mode, partial failure during startup).

Common situations: Custom code invoking internal methods, or an exception during _start_http_mode leaving half-initialized state.

Related errors


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