apple/pkl · error · ProtocolException

Unexpected incoming one-way message: $message

Error message

Unexpected incoming one-way message: $message

What it means

The server's one-way message handler only accepts CloseEvaluator messages; any other one-way message received from the client violates the evaluator-protocol and throws ProtocolException. This signals a protocol version mismatch or a corrupted/unexpected message stream.

Solutions

  1. Verify client and server use the same pkl protocol version.
  2. Check that the client sends only CloseEvaluator as a one-way message.
  3. Fix custom transport implementations to route request messages to the request callback.
  4. Log the raw message to identify which unexpected type was received.

Example fix

// before
transport.sendOneWay(CreateEvaluatorRequest(...)) // server: ProtocolException
// after
transport.sendRequest(CreateEvaluatorRequest(...))
Defensive patterns

Strategy: type-guard

Validate before calling

if (message !is CloseEvaluator) { logger.warn("Refusing to send one-way: ${message::class}"); return }

Type guard

fun isLegalOneWay(m: Message) = m is CloseEvaluator

Try / catch

try { server.start() } catch (e: ProtocolException) { logger.error("Protocol violation: ${e.message}") }

Prevention

When it happens

Trigger: Transport calling the one-way callback during start() with a message type other than CloseEvaluator — e.g. a client sending a request-type message on the one-way channel or an unknown/newer protocol message.

Common situations: Client and server using mismatched protocol versions, a bug in a custom transport implementation routing messages to the wrong channel, or malformed client code sending requests one-way.

Understand the failure class

Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.

Related errors


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

Appendix: source

Thrown at pkl-server/src/main/kotlin/org/pkl/server/Server.kt:73

  companion object {
    fun stream(inputStream: InputStream, outputStream: OutputStream): Server =
      Server(
        MessageTransports.stream(
          ServerMessagePackDecoder(inputStream),
          ServerMessagePackEncoder(outputStream),
          ::log,
        )
      )
  }

  /** Starts listening to incoming messages */
  fun start() {
    transport.start(
      { message ->
        when (message) {
          is CloseEvaluator -> handleCloseEvaluator(message)
          else -> throw ProtocolException("Unexpected incoming one-way message: $message")
        }
      },
      { message ->
        when (message) {
          is CreateEvaluatorRequest -> handleCreateEvaluator(message)
          is EvaluateRequest -> handleEvaluate(message)
          else -> throw ProtocolException("Unexpected incoming request message: $message")
        }
      },
    )
  }

  /**
   * Stops listening to incoming messages, cancels pending evaluation requests, and releases
   * resources held by this server.
   */
  override fun close() {
    transport.closeQuietly()

View on GitHub (pinned to f3efcbfc9b)