{"record":{"id":"2e6310fc1fbcf832","repo":"unionlabs/union","slug":"send-ibc-transaction-failed","errorCode":null,"errorMessage":"send_ibc_transaction failed: {:?}","messagePattern":"send_ibc_transaction failed: (.+?)","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"tools/union-test/src/lib.rs","lineNumber":698,"sourceCode":"    pub async fn send_and_recv<Src: ChainEndpoint, Dst: ChainEndpoint>(\n        &self,\n        source_chain: &Src,\n        contract: Src::Contract,\n        msg: Src::Msg,\n        destination_chain: &Dst,\n        timeout: Duration,\n        signer: &Src::ProviderType,\n    ) -> anyhow::Result<helpers::PacketRecv> {\n        let (packet_hash, _height) = match source_chain\n            .send_ibc_transaction(contract.clone(), msg.clone(), signer)\n            .await\n        {\n            Ok(hash) => {\n                println!(\"send_ibc_tx succeeded with hash: {:?}\", hash);\n                hash\n            }\n            Err(e) => {\n                anyhow::bail!(\"send_ibc_transaction failed: {:?}\", e);\n            }\n        };\n        println!(\n            \"Packet sent from {} to {} with hash: {}\",\n            source_chain.chain_id(),\n            destination_chain.chain_id(),\n            packet_hash\n        );\n        match destination_chain\n            .wait_for_packet_recv(packet_hash, timeout)\n            .await\n        {\n            Ok(evt) => Ok(evt),\n            Err(e) => anyhow::bail!(\"wait_for_packet_recv failed: {:?}\", e),\n        }\n    }\n\n    pub async fn send_and_recv_and_ack<Src: ChainEndpoint, Dst: ChainEndpoint>(","sourceCodeStart":680,"sourceCodeEnd":716,"githubUrl":"https://github.com/unionlabs/union/blob/031785bb6dc6b957c624e62bc64c184409c97d7b/tools/union-test/src/lib.rs#L680-L716","documentation":"Top-level wrapper in union-test's e2e driver (`send_and_recv`): it calls `source_chain.send_ibc_transaction(...)` (EVM or Cosmos implementation depending on chain type) and re-wraps any failure with this message. The real cause is always the attached inner error printed with `{:?}`.","triggerScenarios":"Any failure of the underlying send: cosmos sequence-mismatch exhaustion ('failed to send transaction'), missing wasm-packet_send event, missing tx height, or on EVM a keyring/RPC broadcast failure. In all cases the packet never left the source chain.","commonSituations":"Unfunded or mis-sequenced signer; msg encoding that doesn't produce a packet; RPC issues on the source chain — anything that makes the source-side send step of an e2e test fail.","solutions":["Read the inner error in the bail message and fix that specific cause (funds, sequence, RPC, msg encoding)","If the inner cause is transient (sequence mismatch, RPC hiccup), wait briefly and re-run the test","Verify the source chain signer and contract addresses in the fixture"],"exampleFix":"// before\nsuite.send_and_recv(src, contract, msg, dst, Duration::from_secs(120), &signer).await?; \n// after: one retry for transient source-side send failures\nlet r = suite.send_and_recv(src, contract, msg.clone(), dst, Duration::from_secs(120), &signer).await;\nlet recv = match r {\n    Err(e) if is_transient_send_err(&e) => {\n        tokio::time::sleep(Duration::from_secs(10)).await;\n        suite.send_and_recv(src, contract, msg, dst, Duration::from_secs(120), &signer).await?\n    }\n    r => r?,\n};","handlingStrategy":"try-catch","validationCode":"// pre-flight: source signer can broadcast (cosmos: sequence settles; evm: funds present)\nlet _ = source_chain.get_fee_payer_balance().await?; // fails fast on setup issues","typeGuard":null,"tryCatchPattern":"match suite.send_and_recv(src, contract, msg.clone(), dst, timeout, &signer).await {\n    Ok(r) => Ok(r),\n    Err(e) if e.to_string().starts_with(\"send_ibc_transaction failed\") && is_transient(&e) => {\n        tokio::time::sleep(Duration::from_secs(10)).await;\n        suite.send_and_recv(src, contract, msg, dst, timeout, &signer).await\n    }\n    Err(e) => Err(e),\n}","preventionTips":["Keep source-chain signers funded and dedicated to one test flow","Log the inner error chain (`{:#}`) so wrapper failures are diagnosable","Validate contract/msg fixtures before running the e2e step"],"tags":["rust","ibc","e2e","wrapper","union-test"],"backgroundTag":null,"analyzedSha":"031785bb6dc6b957c624e62bc64c184409c97d7b","analyzedAt":"2026-08-16T06:24:09.996Z","schemaVersion":2},"datasetVersion":"2026-08-16T08:17:34.114Z"}