unionlabs/union · error · anyhow::Error
wait_for_update_client failed: {:?}
Error message
wait_for_update_client failed: {:?} What it means
After a successful send, send_and_get_height waits on the destination chain for the update-client event tied to the send height via destination_chain.wait_for_update_client(height, timeout). This error means no such update-client event was observed within the timeout: typically the relayer did not push a new consensus/client update covering that height, or the query for the event failed. The helper then cannot report the client update height and bails.
Source
Thrown at tools/union-test/src/lib.rs:1008
}
Err(e) => {
anyhow::bail!("send_ibc_transaction failed: {:?}", e);
}
};
println!(
"Packet sent from {} to {} with hash: {} and with height: {}",
source_chain.chain_id(),
destination_chain.chain_id(),
packet_hash,
height
);
let update_client_result: anyhow::Result<helpers::UpdateClient> = match destination_chain
.wait_for_update_client(height, timeout)
.await
{
Ok(evt) => Ok(evt),
Err(e) => anyhow::bail!("wait_for_update_client failed: {:?}", e),
};
println!("Update client event received: {:?}", update_client_result);
Ok(update_client_result.unwrap().height)
}
pub async fn send_and_expect_revert<Src: ChainEndpoint, Dst: ChainEndpoint>(
&self,
source_chain: &Src,
contract: Src::Contract,
msg: Src::Msg,
expected_revert_code: u32,
signer: &Src::ProviderType,
) -> anyhow::Result<()> {
match source_chain
.send_ibc_transaction(contract.clone(), msg.clone(), signer)
.await
{View on GitHub (pinned to 031785bb6d)
Solutions
- Confirm the relayer is running and submitting update-client msgs for the source→destination client pair.
- Increase the timeout so it covers the relayer's update cadence plus block times on both chains.
- Check the destination client is active (not expired) so updates are accepted.
- Verify the height used for the query is the block height the send tx was included in (printed in the 'with height: {}' log).
Defensive patterns
Strategy: retry
Validate before calling
// confirm the destination client of src is active before waiting
let status = dst.query_client_status(src.chain_id()).await?;
anyhow::ensure!(status == ClientStatus::Active, "client not active: {status:?} — updates will not land"); Try / catch
let upd = dst.wait_for_update_client(height, timeout)
.await
.with_context(|| format!("no update-client event covering height {height} within {timeout:?}"))?; Prevention
- Trigger one update-client before the test so you know the relayer cadence; size the wait from it.
- Keep both chains producing blocks during the wait (devnets sometimes stall when idle).
When it happens
Trigger: No relayer running to submit client updates for the destination's client of the source chain, the update-client message skipped because the client was already current but the event query targets the wrong height, or the timeout is shorter than the relayer's update cadence.
Common situations: Test harness started chains but not the relayer; relayer's client-update frequency configured too low for the test window; expired/allow-update misconfigured client; wrong height passed because the send returned the block of a different node view.
Related errors
- wait_for_packet_recv failed: {:?}
- wait_for_packet_ack failed: {:?}
- wait_for_packet_timeout failed: {:?}
- timed out after {:?}
- timed out after {:?}
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/0906366bbc288132.
Report an issue: GitHub.