{"record":{"id":"c36cfaf87768fc8c","repo":"unionlabs/union","slug":"transaction-height-not-found","errorCode":null,"errorMessage":"transaction height not found","messagePattern":"transaction height not found","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"tools/union-test/src/cosmos.rs","lineNumber":782,"sourceCode":"        match err {\n            BroadcastTxCommitError::Query(grpc_err) => {\n                grpc_err.log.contains(\"account sequence mismatch\")\n            }\n            _ => false,\n        }\n    }\n\n    pub async fn send_ibc_transaction(\n        &self,\n        contract: Addr,\n        msg: (Vec<u8>, Vec<Coin>),\n        signer: &LocalSigner,\n    ) -> anyhow::Result<(H256, u64)> {\n        let result = self.send_cosmwasm_transaction(contract, msg, signer).await;\n        let tx_result = result.ok_or_else(|| anyhow!(\"failed to send transaction\"))??;\n        let height = tx_result\n            .height\n            .ok_or_else(|| anyhow!(\"transaction height not found\"))?;\n\n        let send_event = tx_result\n            .tx_result\n            .events\n            .into_iter()\n            .find_map(|e| {\n                if e.ty == \"wasm-packet_send\" {\n                    CosmosSdkEvent::<ModuleEvent>::new(e).ok().map(|e| e.event)\n                } else {\n                    None\n                }\n            })\n            .ok_or_else(|| anyhow!(\"wasm-packet_send event not found\"))?;\n\n        Ok(match send_event {\n            ModuleEvent::WasmPacketSend { packet_hash, .. } => (packet_hash, height.get()),\n            _ => bail!(\"unexpected event variant\"),\n        })","sourceCodeStart":764,"sourceCodeEnd":800,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/tools/union-test/src/cosmos.rs#L764-L800","documentation":"After `broadcast_tx_commit` succeeds, `send_ibc_transaction` reads `TxResponse.height` to report the block height of the IBC send; the cometbft response left it None, so the code errors out. This reflects an RPC response that omitted the height field, not a chain-level failure.","triggerScenarios":"A cometbft RPC endpoint (or proxy/mock) that returns TxResponse without `height` populated; version skew between union-test's cometbft types and the node's JSON-RPC serialization.","commonSituations":"Pointing union-test at a non-standard or proxied RPC; mocked RPC in tests; upgraded chain whose TxResponse schema changed.","solutions":["As a caller, recover the height by querying the tx by hash (`/tx` RPC) instead of trusting the commit response","Switch to a standard cometbft-compatible endpoint","Update union-test to a revision matching the chain's cometbft version"],"exampleFix":"// before\nlet height = tx_result.height.ok_or_else(|| anyhow!(\"transaction height not found\"))?; \n// after: fall back to a by-hash tx query\nlet height = match tx_result.height {\n    Some(h) => h,\n    None => client.rpc.tx(H256::from(hash), false).await?.tx_result.height,\n};","handlingStrategy":"fallback","validationCode":null,"typeGuard":null,"tryCatchPattern":"let height = match tx_result.height {\n    Some(h) => h,\n    None => {\n        // fallback: recover the height from a by-hash tx query\n        let tx = client.rpc.tx(hash_bytes, false).await?;\n        tx.tx_result.height\n    }\n};","preventionTips":["Prefer standard cometbft endpoints that populate TxResponse.height","Keep union-test's cometbft dependency version aligned with the chain"],"tags":["rust","cometbft","rpc","transaction"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}