HKUDS/Vibe-Trading · error · RuntimeError

signal-cli send failed: {response['error']}

Error message

signal-cli send failed: {response['error']}

What it means

signal-cli returned a JSON-RPC response containing an 'error' field when sending a message via the send() method.

Source

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

            if not plain_text and not msg.media:
                return
            recipient_params = self._recipient_params(msg.chat_id)

            chunks = split_message(plain_text, self._MAX_MESSAGE_LEN) if plain_text else [""]
            chunk_styles = _partition_styles(plain_text, chunks, text_styles)
            for i, chunk in enumerate(chunks):
                params: dict[str, Any] = {"message": chunk}
                if chunk_styles[i]:
                    params["textStyle"] = chunk_styles[i]
                params.update(recipient_params)
                if msg.media and i == 0:
                    params["attachments"] = msg.media

                response = await self._send_request("send", params)

                if "error" in response:
                    self.logger.error("Error sending Signal message: {}", response['error'])
                    raise RuntimeError(f"signal-cli send failed: {response['error']}")
                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:

View on GitHub (pinned to 80ffdda44c)

Solutions

  1. Verify the recipient number is registered on Signal (correct E.164 format)
  2. Re-link signal-cli: 'signal-cli -u NUMBER link --device-name ...'
  3. Read response['error'] detail in logs to identify the underlying signal-cli failure
Defensive patterns

Strategy: try-catch

Try / catch

try:
    await signal_channel.send(chat_id, text)
except RuntimeError as e:
    if 'signal-cli send failed' in str(e):
        notify_ops(f'Signal send failed: {e}')  # inspect inner error text

Prevention

When it happens

Trigger: send() called with a recipient that doesn't exist, unregistered number, expired linked device, or attachment path problems; signal-cli embeds the error in the RPC response rather than failing the HTTP call.

Common situations: Wrong phone number format, Signal account unlinked from signal-cli, trust issues after re-linking, or oversized attachments.

Related errors


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