{"record":{"id":"aea1dce8e3ed54c1","repo":"commaai/openpilot","slug":"32000","errorCode":"-32000","errorMessage":"invalid service","messagePattern":"invalid service","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"openpilot/system/athena/athenad.py","lineNumber":357,"sourceCode":"\n  stream = None\n  try:\n    stream, content_length = get_upload_stream(path, compress)\n    response = UPLOAD_SESS.put(upload_item.url,\n                               data=CallbackReader(stream, callback, content_length) if callback else stream,\n                               headers={**upload_item.headers, 'Content-Length': str(content_length)},\n                               timeout=30)\n    return response\n  finally:\n    if stream:\n      stream.close()\n\n\n# security: user should be able to request any message from their car\n@dispatcher.add_method\ndef getMessage(service: str, timeout: int = 1000) -> dict:\n  if service is None or service not in SERVICE_LIST:\n    raise Exception(\"invalid service\")\n\n  socket = messaging.sub_sock(service, timeout=timeout)\n  try:\n    ret = messaging.recv_one(socket)\n\n    if ret is None:\n      raise TimeoutError\n\n    # this is because capnp._DynamicStructReader doesn't have typing information\n    return cast(dict, ret.to_dict())\n  finally:\n    del socket\n\n\n@dispatcher.add_method\ndef getVersion() -> dict[str, str]:\n  build_metadata = get_build_metadata()\n  return {","sourceCodeStart":339,"sourceCodeEnd":375,"githubUrl":"https://github.com/commaai/openpilot/blob/516ec1e68203439a73f340f1d0b3b91eabc626ee/openpilot/system/athena/athenad.py#L339-L375","documentation":"athenad's JSON-RPC method getMessage rejects the request (code -32000) when the service argument is not a string in SERVICE_LIST, the list of cereal messaging services. It exists so remote clients cannot subscribe to arbitrary/nonexistent sockets.","triggerScenarios":"Calling startLocalProxy-style athena API getMessage with service=None, a misspelled name ('carstate' vs 'carState'), or a service that exists in some builds but not the one on the device.","commonSituations":"Typos or wrong casing in companion-app/cabana requests, service renamed between openpilot versions (e.g. a renamed log), client code built against a different cereal revision.","solutions":["Use the exact cereal service name with correct casing, e.g. 'carState', 'deviceState'","Enumerate valid names from cereal services (cereal.SERVICE_LIST) before sending the request","If the name looks right but is rejected, your device build may be older: check the cereal version it was built from"],"exampleFix":"// before\nmsg = {\"jsonrpc\": \"2.0\", \"method\": \"getMessage\", \"params\": {\"service\": \"carstate\"}, \"id\": 1}\n\n// after\nfrom cereal import SERVICE_LIST\nservice = 'carState'\nassert service in SERVICE_LIST\nmsg = {\"jsonrpc\": \"2.0\", \"method\": \"getMessage\", \"params\": {\"service\": service}, \"id\": 1}","handlingStrategy":"validation","validationCode":"from cereal import SERVICE_LIST\n\ndef valid_service(service) -> bool:\n    return isinstance(service, str) and service in SERVICE_LIST","typeGuard":"def is_valid_service(service: object) -> bool:\n    return isinstance(service, str) and service in SERVICE_LIST","tryCatchPattern":null,"preventionTips":["Copy service names verbatim from cereal's service list (mind the camelCase)","Fail fast client-side on unknown services instead of relying on the device error"],"tags":["athena","jsonrpc","messaging","validation"],"backgroundTag":null,"analyzedSha":"516ec1e68203439a73f340f1d0b3b91eabc626ee","analyzedAt":"2026-08-15T00:17:37.461Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}