signalapp/Signal-Server · error · InvalidMessageException

Missing required response attributes!

Error message

Missing required response attributes!

What it means

For RESPONSE_MESSAGE frames, ProtobufWebSocketMessage requires the response to include id, status, and message fields. If any is missing the constructor throws InvalidMessageException with this message, because a response without these cannot be correlated or interpreted by the receiver.

Solutions

  1. Set response id, status, and message when building the WebSocketMessage response
  2. Fix the code path that constructs the response to include all three attributes
  3. Confirm client and server use the same SubProtocol protobuf schema

Example fix

// before
Response.newBuilder().setStatus(200).build()
// after
Response.newBuilder().setId(requestId).setStatus(200).setMessage("OK").build()
Defensive patterns

Strategy: validation

Validate before calling

boolean isCompleteResponse(SubProtocol.WebSocketMessage msg) {
    return msg.getType() == Type.RESPONSE_MESSAGE
        && msg.getResponse().hasId() && msg.getResponse().hasStatus() && msg.getResponse().hasMessage();
}

Type guard

boolean hasResponseAttributes(SubProtocol.WebSocketMessage msg) {
    return msg.hasResponse() && msg.getResponse().hasId()
        && msg.getResponse().hasStatus() && msg.getResponse().hasMessage();
}

Try / catch

try { new ProtobufWebSocketMessage(buffer); } catch (InvalidMessageException e) { logger.warn("malformed response frame: {}", e.getMessage()); }

Prevention

When it happens

Trigger: Building a SubProtocol.WebSocketMessage with type RESPONSE_MESSAGE but omitting response.id, response.status, or response.message before parsing it through the ProtobufWebSocketMessage constructor.

Common situations: Server-side code constructing responses manually and forgetting the message field; test fixtures with partial responses; protobuf field numbers changed across versions so fields land unset.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of signalapp/Signal-Server@100ab61c82 (2026-09-09). Data as JSON: /api/errors/804526b8d2f2a452. Report an issue: GitHub.

Appendix: source

Thrown at websocket-resources/src/main/java/org/whispersystems/websocket/messages/protobuf/ProtobufWebSocketMessage.java:29

import org.whispersystems.websocket.messages.WebSocketRequestMessage;
import org.whispersystems.websocket.messages.WebSocketResponseMessage;
import java.nio.ByteBuffer;

public class ProtobufWebSocketMessage implements WebSocketMessage {

  private final SubProtocol.WebSocketMessage message;

  ProtobufWebSocketMessage(ByteBuffer buffer) throws InvalidMessageException {
    try {
      this.message = SubProtocol.WebSocketMessage.parseFrom(ByteString.copyFrom(buffer));

      if (getType() == Type.REQUEST_MESSAGE) {
        if (!message.getRequest().hasVerb() || !message.getRequest().hasPath()) {
          throw new InvalidMessageException("Missing required request attributes!");
        }
      } else if (getType() == Type.RESPONSE_MESSAGE) {
        if (!message.getResponse().hasId() || !message.getResponse().hasStatus() || !message.getResponse().hasMessage()) {
          throw new InvalidMessageException("Missing required response attributes!");
        }
      }
    } catch (InvalidProtocolBufferException e) {
      throw new InvalidMessageException(e);
    }
  }

  ProtobufWebSocketMessage(SubProtocol.WebSocketMessage message) {
    this.message = message;
  }

  @Override
  public Type getType() {
    if (message.getType().getNumber() == SubProtocol.WebSocketMessage.Type.REQUEST_VALUE &&
        message.hasRequest())
    {
      return Type.REQUEST_MESSAGE;
    } else if (message.getType().getNumber() == SubProtocol.WebSocketMessage.Type.RESPONSE_VALUE &&

View on GitHub (pinned to 100ab61c82)