HKUDS/Vibe-Trading · warning · ConnectionError

Signal SSE stream closed by remote endpoint

Error message

Signal SSE stream closed by remote endpoint

What it means

The SSE stream from signal-cli terminated cleanly (stream context exited) while the channel was still running, treated as a remote disconnect and trigger for reconnect.

Source

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

                                    self.logger.warning(
                                        "Invalid JSON in SSE buffer: {}, data: {}",
                                        e,
                                        data_str[:200],
                                    )
                                finally:
                                    event_buffer = []

                        # "data:" line - accumulate it
                        elif line.startswith("data:"):
                            # SSE spec: strip one optional leading space after "data:".
                            event_buffer.append(line[6:] if line[5:6] == " " else line[5:])

                        # "event:" line - just log it (we only care about data)
                        elif line.startswith("event:"):
                            pass  # Ignore event type for now

                if self._running:
                    raise ConnectionError("Signal SSE stream closed by remote endpoint")

        except asyncio.CancelledError:
            self.logger.info("SSE receive loop cancelled")
            raise
        except Exception as e:
            self.logger.error("Error in SSE receive loop: {}", e)
            raise

    @asynccontextmanager
    async def _safe_handle(self, action: str, payload: Any = None) -> AsyncIterator[None]:
        """Swallow and log any exception from a top-level handler block.

        Logs `self.logger.error` with the action name, the exception, and a
        bounded ``repr`` of the offending payload so the offending input is
        recoverable from logs without having to correlate by timestamp.
        """
        try:
            yield

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Treat as transient: ensure the supervisor/reconnect loop is active
  2. Check why signal-cli dropped the stream (logs, OOM, restart policy)
  3. If behind a proxy, raise its read/idle timeouts for SSE
Defensive patterns

Strategy: retry

Try / catch

except ConnectionError as e:
    if 'closed by remote' in str(e):
        log.info('Stream closed; reconnecting')  # loop handles it

Prevention

When it happens

Trigger: signal-cli shutting down or dropping the event stream during normal operation; the loop re-establishes the connection after this raise.

Common situations: signal-cli restarts (e.g. after link/registration changes), idle connection reaping by middleboxes.

Related errors


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