unionlabs/union · error · anyhow::Error
wasm-packet_send event not found
Error message
wasm-packet_send event not found
What it means
`send_ibc_transaction` scans the committed tx's `tx_result.events` for an event of type `wasm-packet_send` to extract the packet hash; if none is found the tx is treated as not having sent an IBC packet. Events that fail to deserialize into ModuleEvent are silently skipped, so schema mismatch can also hide the event.
Source
Thrown at tools/union-test/src/cosmos.rs:795
) -> anyhow::Result<(H256, u64)> {
let result = self.send_cosmwasm_transaction(contract, msg, signer).await;
let tx_result = result.ok_or_else(|| anyhow!("failed to send transaction"))??;
let height = tx_result
.height
.ok_or_else(|| anyhow!("transaction height not found"))?;
let send_event = tx_result
.tx_result
.events
.into_iter()
.find_map(|e| {
if e.ty == "wasm-packet_send" {
CosmosSdkEvent::<ModuleEvent>::new(e).ok().map(|e| e.event)
} else {
None
}
})
.ok_or_else(|| anyhow!("wasm-packet_send event not found"))?;
Ok(match send_event {
ModuleEvent::WasmPacketSend { packet_hash, .. } => (packet_hash, height.get()),
_ => bail!("unexpected event variant"),
})
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type", content = "attributes")]
pub enum ModuleEvent {
#[serde(rename = "delegate")]
Delegate { validator: String, amount: String },
#[serde(rename = "withdraw_rewards")]
WithdrawRewards { validator: String, amount: String },
#[serde(rename = "wasm-packet_send")]View on GitHub (pinned to 031785bb6d)
Solutions
- Inspect the committed tx's raw events (explorer or /tx RPC) to see what the contract actually emitted
- Verify the contract address is the ucs03-zkgm contract and the msg bytes encode the intended variant
- Check the funds/denom attached to the execute if the flow requires them
- Align union-test/unionlabs versions with the deployed contract's event schema
Example fix
// before: assume any committed tx sent a packet
let (hash, height) = client.send_ibc_transaction(contract, msg, &signer).await?;
// after: check for the send event before relying on it
let sent = tx_result.tx_result.events.iter().any(|e| e.ty == "wasm-packet_send");
if !sent {
let tys: Vec<_> = tx_result.tx_result.events.iter().map(|e| e.ty.clone()).collect();
tracing::warn!(?tys, "no packet_send event; tx did not emit one");
} Defensive patterns
Strategy: try-catch
Validate before calling
// validate before sending: contract is the zkgm contract and the msg is a packet-sending variant anyhow::ensure!(is_zkgm_contract(&contract), "not a ucs03-zkgm contract; tx will not emit wasm-packet_send"); anyhow::ensure!(msg_emits_packet(&msg), "msg variant does not send a packet");
Try / catch
match client.send_ibc_transaction(contract, msg, &signer).await {
Ok((hash, height)) => Ok((hash, height)),
Err(e) if e.to_string().contains("wasm-packet_send event not found") => {
// dump the tx's raw events to diagnose which variant actually executed
tracing::error!(error = %e, "tx committed without packet_send; inspect tx events");
Err(e)
}
Err(e) => Err(e),
} Prevention
- Encode execute msgs from typed structs, not hand-rolled bytes, so the variant is guaranteed
- Pin union-test/unionlabs versions to match the deployed zkgm contract's event schema
- Verify the target contract address comes from the deployment fixture, not a literal
When it happens
Trigger: The execute message ran but did not send a packet: wrong contract address (not the zkgm contract); msg bytes encode a different variant (e.g. a call that doesn't emit packet_send); insufficient funds attached for a transfer-style message; the wasm event's attributes don't fit the ModuleEvent schema this crate version expects, so deserialization fails and the event is skipped.
Common situations: Test encodes the wrong ExecuteMsg variant; contract reverts inside a submessage while the outer tx still succeeds; union-test / unionlabs version out of sync with the deployed zkgm contract's event format.
Related errors
AI-assisted analysis of unionlabs/union@031785bb6d (2026-08-16).
Data as JSON: /api/errors/394782dd64715a3e.
Report an issue: GitHub.