apple/pkl · error · ProtocolException

Cannot receive request messages before transport start.

Error message

Cannot receive request messages before transport start.

What it means

AbstractMessageTransport's default RequestHandler throws this ProtocolException when a request message arrives before the transport is started. Like the one-way variant, it indicates start() was never called, so no request handler was registered to serve incoming requests.

Solutions

  1. Call transport.start() before any message can be accepted on the connection
  2. Delay accepting bytes/messages from the wire until handlers are registered
  3. Add an integration test that connects and sends a request immediately to catch the race
  4. In server code, only register the connection with the message loop after start() succeeds

Example fix

// before
transport.onConnection(conn -> conn.accept(msg)); // default handler throws
// after
transport.start();
transport.onConnection(conn -> conn.accept(msg));
Defensive patterns

Strategy: validation

Validate before calling

assert transportReady.get() : "transport must be started before requests arrive";

Type guard

null

Try / catch

try { transport.accept(request); } catch (ProtocolException e) { LOG.error("request before start()"); transport.start(); /* then fail the request cleanly */ }

Prevention

When it happens

Trigger: A Message.Request arrives and is dispatched via accept() before start() replaced the default throwing requestHandler.

Common situations: Client connects and immediately sends a request while the server-side transport has not called start(); async initialization ordering bugs; tests constructing a transport and pumping messages without starting it.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of apple/pkl@f3efcbfc9b (2026-09-08). Data as JSON: /api/errors/24ce91eb5936f651. Report an issue: GitHub.

Appendix: source

Thrown at pkl-core/src/main/java/org/pkl/core/messaging/MessageTransports.java:135

      assert other != null;
      other.accept(message);
    }

    public void setOther(DirectMessageTransport other) {
      this.other = other;
    }
  }

  public abstract static class AbstractMessageTransport implements MessageTransport {

    private final Logger logger;
    private MessageTransport.OneWayHandler oneWayHandler =
        (msg) -> {
          throw new ProtocolException("Cannot receive one-way messages before transport start.");
        };
    private MessageTransport.RequestHandler requestHandler =
        (msg) -> {
          throw new ProtocolException("Cannot receive request messages before transport start.");
        };
    private final Map<Long, ResponseHandler> responseHandlers = new ConcurrentHashMap<>();

    protected AbstractMessageTransport(Logger logger) {
      this.logger = logger;
    }

    protected void log(String message, Object... args) {
      var formatter = new MessageFormat(message);
      logger.log(formatter.format(args));
    }

    protected abstract void doStart() throws ProtocolException, IOException;

    protected abstract void doClose();

    protected abstract void doSend(Message message) throws ProtocolException, IOException;

View on GitHub (pinned to f3efcbfc9b)