{"record":{"id":"6702e1e91226dddd","repo":"iflytek/astron-agent","slug":"rpa-request-error","errorCode":"RPA_REQUEST_ERROR","errorMessage":"{frame.message}","messagePattern":"\\{frame\\.message\\}","errorType":"error_code","errorClass":"CustomException","httpStatus":null,"severity":"error","filePath":"core/workflow/engine/nodes/rpa/rpa_node.py","lineNumber":99,"sourceCode":"                    }\n                )\n\n            async with aiohttp.ClientSession(\n                timeout=ClientTimeout(total=24 * 60 * 60, sock_connect=30)\n            ) as session:\n                async with session.post(\n                    url=url, headers=headers, json=req_body\n                ) as response:\n                    async for line in response.content:\n                        msg = line.decode(\"utf-8\")\n                        if not msg.startswith(\"data:\"):\n                            continue\n                        await span.add_info_event_async(f\"recv: {msg}\")\n                        frame = _StreamResponse.model_validate_json(\n                            msg.removeprefix(\"data:\")\n                        )\n                        if frame.code != 0:\n                            raise CustomException(\n                                err_code=CodeEnum.RPA_REQUEST_ERROR,\n                                err_msg=frame.message,\n                            )\n                        data = frame.data if frame.data is not None else {}\n            outputs.update(\n                {\n                    output: data.get(output)\n                    for output in self.output_identifier\n                    if output in data\n                }\n            )\n\n            return NodeRunResult(\n                status=status,\n                inputs=inputs,\n                outputs=outputs,\n                node_id=self.node_id,\n                node_type=self.node_type,","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/iflytek/astron-agent/blob/5e758547a83371a5a4b29dadf4ac03e8dd527635/core/workflow/engine/nodes/rpa/rpa_node.py#L81-L117","documentation":"The RPA node consumes a streaming HTTP/SSE response from the RPA service. Each `data:` frame is validated into `_StreamResponse`; if the frame's business `code` is non-zero, the node raises RPA_REQUEST_ERROR carrying the frame's `message` verbatim — this is the RPA service reporting a business-level failure for the request.","triggerScenarios":"async_execute -> execute reads an SSE frame where `frame.code != 0` after `_StreamResponse.model_validate_json(msg.removeprefix(\"data:\"))` — i.e. the remote RPA backend returned an error frame for the submitted task.","commonSituations":"RPA service downtime or internal error; invalid RPA task parameters (wrong robot ID, missing workflow key); RPA license/quota exhausted; auth token for the RPA platform expired; upstream robot execution failure at runtime.","solutions":["Read frame.message (the error text) to get the RPA service's own failure reason and fix the task parameters accordingly.","Verify RPA service availability and credentials (endpoint URL, API key/robot configuration) in the node settings.","Check RPA platform quotas/licensing if the message indicates limit exhaustion.","Add retry with backoff for transient upstream errors (5xx-like codes) in the node or at the RPA service."],"exampleFix":"// before: fire-and-forget stream read\nfor msg in resp:\n    frame = _StreamResponse.model_validate_json(msg.removeprefix(\"data:\"))\n\n// after: bounded retries for transient codes\nfor attempt in range(3):\n    try:\n        return await run_rpa_stream(payload)\n    except CustomException as e:\n        if is_transient(e) and attempt < 2:\n            await asyncio.sleep(2 ** attempt)\n            continue\n        raise","handlingStrategy":"try-catch","validationCode":"def rpa_node_config_ok(cfg: dict) -> bool:\n    return bool(cfg.get(\"endpoint\")) and bool(cfg.get(\"api_key\")) and bool(cfg.get(\"robot_id\"))","typeGuard":"def is_error_frame(frame: _StreamResponse) -> bool:\n    return frame.code != 0","tryCatchPattern":"try:\n    result = await run_rpa_node(...)\nexcept CustomException as e:\n    if e.err_code == CodeEnum.RPA_REQUEST_ERROR:\n        logger.error(f\"RPA service rejected task: {e.err_msg}\")\n        if is_transient_rpa_failure(str(e.err_msg)):\n            result = await retry_with_backoff(run_rpa_node, attempts=3)\n        else:\n            raise\n    else:\n        raise","preventionTips":["Validate RPA endpoint, credentials, and robot configuration before deployment.","Retry only transient upstream failures with exponential backoff.","Monitor RPA service health and quotas.","Surface frame.message to the operator — it names the exact upstream failure."],"tags":["rpa","sse","upstream-error","streaming"],"backgroundTag":"upstream-api-error","analyzedSha":"5e758547a83371a5a4b29dadf4ac03e8dd527635","analyzedAt":"2026-09-12T08:03:51.356Z","contentChangedAt":"2026-09-12T08:03:51.356Z","schemaVersion":2},"datasetVersion":"2026-09-19T12:17:13.211Z"}