unionlabs/union · error · anyhow::Error
timed out after {:?}
Error message
timed out after {:?} What it means
`EvmClient::wait_for_event` wraps its polling loop (checks block number every 10s, scans each new block's logs filtered by `ibc_handler_address`) in `tokio::time::timeout(timeout, ...)`; this error means the deadline elapsed before `expected_event_count` matching IBC events were observed.
Source
Thrown at tools/union-test/src/evm.rs:191
return Err(anyhow::anyhow!("get_logs RPC error: {}", e));
}
};
for log in logs {
if let Ok(ibc_event) = IbcEvents::decode_log(&log.inner)
&& let Some(event) = filter_fn(ibc_event.data)
{
events.push(event);
}
}
prev_latest += 1u64;
}
tokio::time::sleep(Duration::from_secs(10)).await;
}
})
.await
.map_err(|_| anyhow::anyhow!("timed out after {:?}", timeout))?
}
pub async fn wait_for_create_client(
&self,
timeout: Duration,
) -> anyhow::Result<helpers::CreateClientConfirm> {
Ok(self
.wait_for_event(
|e| match e {
IbcEvents::CreateClient(ev) => Some(helpers::CreateClientConfirm {
client_id: ev.client_id,
}),
_ => None,
},
timeout,
1,
)
.await?View on GitHub (pinned to 031785bb6d)
Solutions
- Increase the `timeout` Duration passed to the wait helper
- Verify `ibc_handler_address` is the deployed IBC contract whose logs you need
- Confirm the chain produces blocks and the relayer is running
- Start the wait before triggering the action that emits the event
Example fix
// before let evt = evm.wait_for_create_client(Duration::from_secs(120)).await?; // after let evt = evm.wait_for_create_client(Duration::from_secs(1200)).await?;
Defensive patterns
Strategy: retry
Validate before calling
// pre-flight: chain is producing blocks let b1 = evm.provider.get_block_number().await?; tokio::time::sleep(Duration::from_secs(10)).await; let b2 = evm.provider.get_block_number().await?; anyhow::ensure!(b2 > b1, "EVM chain stalled; wait_for_event will time out");
Try / catch
match evm.wait_for_event(filter, timeout, n).await {
Ok(evts) => Ok(evts),
Err(e) if e.to_string().contains("timed out after") => {
// verify relayer + handler address, then retry with a longer timeout
evm.wait_for_event(filter, timeout * 2, n).await
}
Err(e) => Err(e),
} Prevention
- Confirm the relayer is running before starting waits that depend on relayed packets
- Start the wait before triggering the emitting action so the starting block precedes the event
- Double-check ibc_handler_address against the deployed IBC contract
When it happens
Trigger: The watched event never lands: relayer stopped so packets are never received/acked; `ibc_handler_address` is wrong so the relevant logs are filtered out; the event fired before the wait started (scan begins at the block number at wait start); the EVM chain stalled.
Common situations: Relayer down between devnets; timeout too short for slow proof-verification chains; test fixture configured with a stale handler address; anvil snapshot reverted past the emitting block.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- timed out after {:?}
- wait_for_packet_recv failed: {:?}
- wait_for_packet_ack failed: {:?}
- wait_for_packet_timeout failed: {:?}
- wait_for_update_client failed: {:?}
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/6c20b757f261bd98.
Report an issue: GitHub.