{"record":{"id":"1f9156a0edd654a3","repo":"commaai/openpilot","slug":"not-a-valid-request-or-response","errorCode":null,"errorMessage":"not a valid request or response","messagePattern":"not a valid request or response","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"warning","filePath":"openpilot/system/athena/athenad.py","lineNumber":228,"sourceCode":"  finally:\n    for thread in threads:\n      cloudlog.debug(f\"athena.joining {thread.name}\")\n      thread.join()\n\n\ndef jsonrpc_handler(end_event: threading.Event) -> None:\n  dispatcher[\"startLocalProxy\"] = partial(startLocalProxy, end_event)\n  while not end_event.is_set():\n    try:\n      data = recv_queue.get(timeout=1)\n      msg = loads(data)\n      if is_call(msg):\n        cloudlog.event(\"athena.jsonrpc_handler.call_method\", data=data)\n        send_queue_push(handle(msg, dispatcher), SEND_PRIORITY_HIGH)\n      elif is_response(msg):\n        log_recv_queue.put_nowait(data)\n      else:\n        raise Exception(\"not a valid request or response\")\n    except queue.Empty:\n      pass\n    except Exception as e:\n      cloudlog.exception(\"athena jsonrpc handler failed\")\n      send_queue_push(json.dumps({\"error\": str(e)}), SEND_PRIORITY_HIGH)\n\n\ndef retry_upload(tid: int, end_event: threading.Event, increase_count: bool = True) -> None:\n  item = cur_upload_items[tid]\n  if item is not None and item.retry_count < MAX_RETRY_COUNT:\n    new_retry_count = item.retry_count + 1 if increase_count else item.retry_count\n\n    item = replace(\n      item,\n      retry_count=new_retry_count,\n      progress=0,\n      current=False\n    )","sourceCodeStart":210,"sourceCodeEnd":246,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/system/athena/athenad.py#L210-L246","documentation":"Raised in athenad's jsonrpc_handler loop when an incoming websocket message parses as JSON but is neither a call (no 'method' key) nor a response (no 'id' plus 'result'/'error'). Per JSON-RPC 2.0 such a payload is invalid, so the handler raises; the surrounding except pushes a generic error reply back to the cloud.","triggerScenarios":"The server/CLI sends a bare JSON array, string, or an object like {\"foo\": 1} over the athena websocket; loads() succeeds (it is valid JSON, a dict) but is_call and is_response both return False.","commonSituations":"Hand-crafted test clients not following JSON-RPC 2.0 envelope, a backend bug emitting ack objects without id, or protocol version skew between device and cloud.","solutions":["Send proper JSON-RPC 2.0 envelopes: calls need 'method' (+ optional params/id), responses need 'id' plus 'result' or 'error'","If you control the sender, validate messages client-side with the same is_call/is_response logic","Inspect the logged athena.jsonrpc_handler payloads (cloudlog) to find the malformed sender"],"exampleFix":"// before\nws.send(json.dumps({\"note\": \"hi\"}))\n\n// after\nws.send(json.dumps({\"jsonrpc\": \"2.0\", \"method\": \"getMessage\", \"params\": {\"service\": \"carState\"}, \"id\": 1}))","handlingStrategy":"validation","validationCode":"from openpilot.system.athena.rpc import is_call, is_response\n\ndef valid_envelope(msg: dict) -> bool:\n    return is_call(msg) or is_response(msg)","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always use the jsonrpc 2.0 envelope on the athena websocket","Replay suspected messages against is_call/is_response before shipping client code"],"tags":["jsonrpc","athena","protocol","validation"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}