{"record":{"id":"74fc3dd3628e8c5e","repo":"canopy-network/canopy","slug":"handshake-failed-response-error-msg","errorCode":null,"errorMessage":"Handshake failed: ${response.error.msg}","messagePattern":"Handshake failed: (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt","lineNumber":107,"sourceCode":"     * Perform handshake with FSM\n     */\n    private fun handshake() {\n        logger.info { \"Handshaking with FSM\" }\n\n        val configMsg = PluginToFSM.newBuilder()\n            .setId(0)\n            .setConfig(ContractConfig.toPluginConfig())\n            .build()\n\n        val response = sendSync(null, configMsg)\n\n        when {\n            response.hasConfig() -> {\n                fsmConfig = response.config\n                logger.info { \"Handshake complete\" }\n            }\n            response.hasError() -> {\n                throw Exception(\"Handshake failed: ${response.error.msg}\")\n            }\n            else -> {\n                throw Exception(\"Unexpected handshake response\")\n            }\n        }\n    }\n\n    /**\n     * Read state from FSM\n     */\n    fun stateRead(contract: Contract, request: PluginStateReadRequest): PluginStateReadResponse {\n        val msg = PluginToFSM.newBuilder()\n            .setId(contract.fsmId)\n            .setStateRead(request)\n            .build()\n\n        val response = sendSync(contract, msg)\n","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/canopy-network/canopy/blob/ee8197d91dd410f6592cb650a94c925ee6dc8bad/plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt#L89-L125","documentation":"Thrown in PluginClient.handshake when the FSM's reply to the config handshake message carries an error field; the FSM-side error message is embedded. It means the FSM rejected the plugin's contract configuration at startup, so the plugin cannot proceed to normal operation.","triggerScenarios":"Thrown at plugin/kotlin/src/main/kotlin/com/canopy/plugin/PluginClient.kt:107 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Read the embedded FSM error message to see why the config was rejected and align ContractConfig with FSM expectations.","Verify the FSM is running a compatible protocol version before restarting.","Retry the handshake after fixing the config; the exception propagates from start(), so the plugin restarts."],"exampleFix":null,"handlingStrategy":"try-catch","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"}