{"record":{"id":"753d5efd978baa62","repo":"HKUDS/Vibe-Trading","slug":"signal-cli-send-failed-response-error","errorCode":null,"errorMessage":"signal-cli send failed: {response['error']}","messagePattern":"signal-cli send failed: (.+?)","errorType":"error_code","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"agent/src/channels/signal.py","lineNumber":575,"sourceCode":"            if not plain_text and not msg.media:\n                return\n            recipient_params = self._recipient_params(msg.chat_id)\n\n            chunks = split_message(plain_text, self._MAX_MESSAGE_LEN) if plain_text else [\"\"]\n            chunk_styles = _partition_styles(plain_text, chunks, text_styles)\n            for i, chunk in enumerate(chunks):\n                params: dict[str, Any] = {\"message\": chunk}\n                if chunk_styles[i]:\n                    params[\"textStyle\"] = chunk_styles[i]\n                params.update(recipient_params)\n                if msg.media and i == 0:\n                    params[\"attachments\"] = msg.media\n\n                response = await self._send_request(\"send\", params)\n\n                if \"error\" in response:\n                    self.logger.error(\"Error sending Signal message: {}\", response['error'])\n                    raise RuntimeError(f\"signal-cli send failed: {response['error']}\")\n                else:\n                    self.logger.debug(\n                        f\"Signal message sent, timestamp: {response.get('result', {}).get('timestamp')}\"\n                    )\n\n        except Exception:\n            self.logger.exception(\"Error sending Signal message\")\n            raise\n        finally:\n            # Keep typing active across progress updates; stop on the final reply.\n            if not is_progress_message:\n                # Avoid immediate START->STOP for fast responses, which can be invisible\n                # in some Signal clients. Let indicator expire naturally (~15s).\n                await self._stop_typing(msg.chat_id, send_stop=False)\n\n    async def _sse_receive_loop(self) -> None:\n        \"\"\"Receive messages via Server-Sent Events (HTTP mode).\"\"\"\n        if not self._http:","sourceCodeStart":557,"sourceCodeEnd":593,"githubUrl":"https://github.com/HKUDS/Vibe-Trading/blob/80ffdda44c5c4db0dd84d70e051cca591cea67df/agent/src/channels/signal.py#L557-L593","documentation":"signal-cli returned a JSON-RPC response containing an 'error' field when sending a message via the send() method.","triggerScenarios":"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.","commonSituations":"Wrong phone number format, Signal account unlinked from signal-cli, trust issues after re-linking, or oversized attachments.","solutions":["Verify the recipient number is registered on Signal (correct E.164 format)","Re-link signal-cli: 'signal-cli -u NUMBER link --device-name ...'","Read response['error'] detail in logs to identify the underlying signal-cli failure"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try:\n    await signal_channel.send(chat_id, text)\nexcept RuntimeError as e:\n    if 'signal-cli send failed' in str(e):\n        notify_ops(f'Signal send failed: {e}')  # inspect inner error text","preventionTips":["Validate recipient numbers (E.164) before sending","Monitor signal-cli link status; alert before trust expires"],"tags":["signal","send","rpc"],"backgroundTag":"rpc-send-failed","analyzedSha":"80ffdda44c5c4db0dd84d70e051cca591cea67df","analyzedAt":"2026-08-28T12:46:38.989Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}