TooTallNate/Java-WebSocket · error · IllegalArgumentException

Only Opcode.BINARY or Opcode.TEXT are allowed

Error message

Only Opcode.BINARY or  Opcode.TEXT are allowed

What it means

Draft.continuousFrame builds a frame for streaming messages, but per RFC 6455 only TEXT and BINARY opcodes are valid for message data frames; control/other opcodes (PING, PONG, CLOSE, CONTINUOUS) are rejected with this IllegalArgumentException before any frame is created.

Solutions

  1. Pass only Opcode.TEXT or Opcode.BINARY to continuousFrame
  2. Use the high-level WebSocket send methods (send/sendFragmentedFrame) instead of calling draft APIs directly
  3. For ping/pong/close, use the dedicated API (webSocket.sendPing, close) rather than building frames manually
  4. Add a guard/assert on the opcode before calling

Example fix

// before
draft.continuousFrame(Opcode.PING, payload, true);
// after
draft.continuousFrame(Opcode.BINARY, payload, true);
Defensive patterns

Strategy: validation

Validate before calling

private static void requireDataFrame(Opcode op) {
  if (op != Opcode.TEXT && op != Opcode.BINARY)
    throw new IllegalArgumentException("continuousFrame requires TEXT or BINARY, got " + op);
}

Try / catch

try {
  frames = draft.continuousFrame(op, buffer, fin);
} catch (IllegalArgumentException e) {
  logger.error("Invalid opcode for data frame: {}", e.getMessage());
}

Prevention

When it happens

Trigger: Calling draft.continuousFrame(Opcode.PING/PONG/CLOSE/CONTINUOUS, buffer, fin) directly, or code that computes the Opcode dynamically and passes a control opcode.

Common situations: Low-level users of the draft API hand-rolling fragmentation instead of using WebSocketImpl.send, refactoring that mixes control-frame creation with data-frame streaming, copying examples that pass Opcode values around.

Understand the failure class

Background: Invalid enum value errors: "Unknown type", "Invalid scope", "must be one of" — when a string is not on the library's allowed list — this error's family across 23 libraries.

Related errors


AI-assisted analysis of TooTallNate/Java-WebSocket@afeacbf8c0 (2026-09-09). Data as JSON: /api/errors/c36dc58b46f2e6e4. Report an issue: GitHub.

Appendix: source

Thrown at src/main/java/org/java_websocket/drafts/Draft.java:212

  public abstract List<Framedata> createFrames(ByteBuffer binary, boolean mask);

  public abstract List<Framedata> createFrames(String text, boolean mask);


  /**
   * Handle the frame specific to the draft
   *
   * @param webSocketImpl the websocketimpl used for this draft
   * @param frame         the frame which is supposed to be handled
   * @throws InvalidDataException will be thrown on invalid data
   */
  public abstract void processFrame(WebSocketImpl webSocketImpl, Framedata frame)
      throws InvalidDataException;

  public List<Framedata> continuousFrame(Opcode op, ByteBuffer buffer, boolean fin) {
    if (op != Opcode.BINARY && op != Opcode.TEXT) {
      throw new IllegalArgumentException("Only Opcode.BINARY or  Opcode.TEXT are allowed");
    }
    DataFrame bui = null;
    if (continuousFrameType != null) {
      bui = new ContinuousFrame();
    } else {
      continuousFrameType = op;
      if (op == Opcode.BINARY) {
        bui = new BinaryFrame();
      } else if (op == Opcode.TEXT) {
        bui = new TextFrame();
      }
    }
    bui.setPayload(buffer);
    bui.setFin(fin);
    try {
      bui.isValid();
    } catch (InvalidDataException e) {
      throw new IllegalArgumentException(

View on GitHub (pinned to afeacbf8c0)