canopy-network/canopy · error · kotlin.Exception

Unexpected query response

Error message

Unexpected query response

What it means

Thrown in PluginClient.queryState when the FSM's response to a detached query request has neither a query payload nor an error — an out-of-protocol reply. The query's outcome is undeterminable, pointing at message-stream desynchronization between plugin and FSM.

Source

Thrown at plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt:191

            .build()

        // detached send: no Contract context is tracked for this request id
        val response = sendSync(null, msg)

        return when {
            response.hasQuery() -> {
                val query = response.query
                // surface any FSM-side error attached to the query response
                if (query.hasError() && query.error.code != 0L) {
                    PluginStateReadResponse.newBuilder().setError(query.error).build()
                } else {
                    query.read
                }
            }
            response.hasError() -> PluginStateReadResponse.newBuilder()
                .setError(response.error)
                .build()
            else -> throw Exception("Unexpected query response")
        }
    }

    /**
     * Start listening for inbound messages from FSM
     */
    private fun startListening() {
        thread(isDaemon = true, name = "plugin-listener") {
            try {
                while (socket != null && !socket!!.isClosed) {
                    val msg = receiveMessage()
                    if (msg == null) {
                        // EOF or error - connection closed
                        logger.info { "Connection closed by FSM" }
                        break
                    }
                    handleMessage(msg)
                }

View on GitHub (pinned to ee8197d91d)

Solutions

  1. Confirm detached (no-contract) request ids do not collide with contract-scoped ids in the pending map.
  2. Verify proto schema compatibility between plugin and FSM.
  3. Restart the plugin/FSM link and retry the query.
Defensive patterns

Strategy: retry

When it happens

Trigger: Thrown at plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt:191 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of canopy-network/canopy@ee8197d91d (2026-09-06). Data as JSON: /api/errors/e9d8269c63550eb8. Report an issue: GitHub.