{"record":{"id":"0b0fb473d9fb4ffa","repo":"signalapp/Signal-Server","slug":"missing-required-request-attributes","errorCode":null,"errorMessage":"Missing required request attributes!","messagePattern":"Missing required request attributes!","errorType":"validation","errorClass":"InvalidMessageException","httpStatus":null,"severity":"error","filePath":"websocket-resources/src/main/java/org/whispersystems/websocket/messages/protobuf/ProtobufWebSocketMessage.java","lineNumber":25,"sourceCode":"import com.google.protobuf.ByteString;\nimport com.google.protobuf.InvalidProtocolBufferException;\nimport org.whispersystems.websocket.messages.InvalidMessageException;\nimport org.whispersystems.websocket.messages.WebSocketMessage;\nimport org.whispersystems.websocket.messages.WebSocketRequestMessage;\nimport org.whispersystems.websocket.messages.WebSocketResponseMessage;\nimport java.nio.ByteBuffer;\n\npublic class ProtobufWebSocketMessage implements WebSocketMessage {\n\n  private final SubProtocol.WebSocketMessage message;\n\n  ProtobufWebSocketMessage(ByteBuffer buffer) throws InvalidMessageException {\n    try {\n      this.message = SubProtocol.WebSocketMessage.parseFrom(ByteString.copyFrom(buffer));\n\n      if (getType() == Type.REQUEST_MESSAGE) {\n        if (!message.getRequest().hasVerb() || !message.getRequest().hasPath()) {\n          throw new InvalidMessageException(\"Missing required request attributes!\");\n        }\n      } else if (getType() == Type.RESPONSE_MESSAGE) {\n        if (!message.getResponse().hasId() || !message.getResponse().hasStatus() || !message.getResponse().hasMessage()) {\n          throw new InvalidMessageException(\"Missing required response attributes!\");\n        }\n      }\n    } catch (InvalidProtocolBufferException e) {\n      throw new InvalidMessageException(e);\n    }\n  }\n\n  ProtobufWebSocketMessage(SubProtocol.WebSocketMessage message) {\n    this.message = message;\n  }\n\n  @Override\n  public Type getType() {\n    if (message.getType().getNumber() == SubProtocol.WebSocketMessage.Type.REQUEST_VALUE &&","sourceCodeStart":7,"sourceCodeEnd":43,"githubUrl":"https://github.com/signalapp/Signal-Server/blob/100ab61c82627582c867d19e1c0561ba2781e927/websocket-resources/src/main/java/org/whispersystems/websocket/messages/protobuf/ProtobufWebSocketMessage.java#L7-L43","documentation":"A ProtobufWebSocketMessage parsed from a WebSocket frame of type REQUEST_MESSAGE must carry a request with both verb and path set. When either protobuf field is absent the constructor throws InvalidMessageException with this message, since an HTTP-like request without a verb or path cannot be dispatched.","triggerScenarios":"Constructing SubProtocol.WebSocketMessage with type REQUEST_MESSAGE but leaving request.verb or request.path unset, then serializing and parsing it via ProtobufWebSocketMessage(ByteBuffer).","commonSituations":"Client library bug omitting required fields; hand-crafted protobuf payloads in tests; schema/version drift where new clients skip fields older parsers require.","solutions":["Populate request.verb and request.path before sending the WebSocketMessage","Fix the client-side builder to set all required request attributes","Verify protobuf schema versions match between client and server"],"exampleFix":"// before\nWebSocketMessage.newBuilder().setType(REQUEST_MESSAGE).setRequest(Request.newBuilder().setVerb(\"GET\")).build()\n// after\nWebSocketMessage.newBuilder().setType(REQUEST_MESSAGE).setRequest(Request.newBuilder().setVerb(\"GET\").setPath(\"/v1/messages\")).build()","handlingStrategy":"validation","validationCode":"boolean isCompleteRequest(SubProtocol.WebSocketMessage msg) {\n    return msg.getType() == Type.REQUEST_MESSAGE\n        && msg.getRequest().hasVerb() && msg.getRequest().hasPath();\n}","typeGuard":"boolean hasRequestAttributes(SubProtocol.WebSocketMessage msg) {\n    return msg.hasRequest() && msg.getRequest().hasVerb() && msg.getRequest().hasPath();\n}","tryCatchPattern":"try { new ProtobufWebSocketMessage(buffer); } catch (InvalidMessageException e) { logger.warn(\"malformed request frame: {}\", e.getMessage()); }","preventionTips":["Always set verb and path on request frames","Share one protobuf schema definition across client and server","Add unit tests for minimal/complete frame builders"],"tags":["websocket","protobuf","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"100ab61c82627582c867d19e1c0561ba2781e927","analyzedAt":"2026-09-09T13:29:47.883Z","contentChangedAt":"2026-09-09T13:29:47.883Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}