{"record":{"id":"e9d8269c63550eb8","repo":"canopy-network/canopy","slug":"unexpected-query-response","errorCode":null,"errorMessage":"Unexpected query response","messagePattern":"Unexpected query response","errorType":"exception","errorClass":"kotlin.Exception","httpStatus":null,"severity":"error","filePath":"plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt","lineNumber":191,"sourceCode":"            .build()\n\n        // detached send: no Contract context is tracked for this request id\n        val response = sendSync(null, msg)\n\n        return when {\n            response.hasQuery() -> {\n                val query = response.query\n                // surface any FSM-side error attached to the query response\n                if (query.hasError() && query.error.code != 0L) {\n                    PluginStateReadResponse.newBuilder().setError(query.error).build()\n                } else {\n                    query.read\n                }\n            }\n            response.hasError() -> PluginStateReadResponse.newBuilder()\n                .setError(response.error)\n                .build()\n            else -> throw Exception(\"Unexpected query response\")\n        }\n    }\n\n    /**\n     * Start listening for inbound messages from FSM\n     */\n    private fun startListening() {\n        thread(isDaemon = true, name = \"plugin-listener\") {\n            try {\n                while (socket != null && !socket!!.isClosed) {\n                    val msg = receiveMessage()\n                    if (msg == null) {\n                        // EOF or error - connection closed\n                        logger.info { \"Connection closed by FSM\" }\n                        break\n                    }\n                    handleMessage(msg)\n                }","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt#L173-L209","documentation":"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.","triggerScenarios":"Thrown at plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt:191 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Confirm detached (no-contract) request ids do not collide with contract-scoped ids in the pending map.","Verify proto schema compatibility between plugin and FSM.","Restart the plugin/FSM link and retry the query."],"exampleFix":null,"handlingStrategy":"retry","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"ee8197d91dd410f6592cb650a94c925ee6dc8bad","analyzedAt":"2026-09-06T09:30:15.973Z","contentChangedAt":"2026-09-06T09:30:15.973Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}