{"record":{"id":"cfe66fbb52737ed0","repo":"apple/pkl","slug":"unexpected-incoming-one-way-message-message","errorCode":null,"errorMessage":"Unexpected incoming one-way message: $message","messagePattern":"Unexpected incoming one-way message: \\$message","errorType":"exception","errorClass":"ProtocolException","httpStatus":null,"severity":"error","filePath":"pkl-server/src/main/kotlin/org/pkl/server/Server.kt","lineNumber":73,"sourceCode":"\n  companion object {\n    fun stream(inputStream: InputStream, outputStream: OutputStream): Server =\n      Server(\n        MessageTransports.stream(\n          ServerMessagePackDecoder(inputStream),\n          ServerMessagePackEncoder(outputStream),\n          ::log,\n        )\n      )\n  }\n\n  /** Starts listening to incoming messages */\n  fun start() {\n    transport.start(\n      { message ->\n        when (message) {\n          is CloseEvaluator -> handleCloseEvaluator(message)\n          else -> throw ProtocolException(\"Unexpected incoming one-way message: $message\")\n        }\n      },\n      { message ->\n        when (message) {\n          is CreateEvaluatorRequest -> handleCreateEvaluator(message)\n          is EvaluateRequest -> handleEvaluate(message)\n          else -> throw ProtocolException(\"Unexpected incoming request message: $message\")\n        }\n      },\n    )\n  }\n\n  /**\n   * Stops listening to incoming messages, cancels pending evaluation requests, and releases\n   * resources held by this server.\n   */\n  override fun close() {\n    transport.closeQuietly()","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/apple/pkl/blob/f3efcbfc9b60d30053b0536d664948d7aa1b8673/pkl-server/src/main/kotlin/org/pkl/server/Server.kt#L55-L91","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Verify client and server use the same pkl protocol version.","Check that the client sends only CloseEvaluator as a one-way message.","Fix custom transport implementations to route request messages to the request callback.","Log the raw message to identify which unexpected type was received."],"exampleFix":"// before\ntransport.sendOneWay(CreateEvaluatorRequest(...)) // server: ProtocolException\n// after\ntransport.sendRequest(CreateEvaluatorRequest(...))","handlingStrategy":"type-guard","validationCode":"if (message !is CloseEvaluator) { logger.warn(\"Refusing to send one-way: ${message::class}\"); return }","typeGuard":"fun isLegalOneWay(m: Message) = m is CloseEvaluator","tryCatchPattern":"try { server.start() } catch (e: ProtocolException) { logger.error(\"Protocol violation: ${e.message}\") }","preventionTips":["Pin matching pkl client/server versions","Send requests only via the request channel","Unit-test custom transports against the protocol spec","Log all outgoing message types in debug mode"],"tags":["protocol","server","messaging"],"backgroundTag":"unexpected-api-response-shape","analyzedSha":"f3efcbfc9b60d30053b0536d664948d7aa1b8673","analyzedAt":"2026-09-08T13:10:45.570Z","contentChangedAt":"2026-09-08T13:10:45.570Z","schemaVersion":2},"datasetVersion":"2026-09-17T15:17:12.973Z"}