diem/diem · error
expected same number of event lists as transactions, receive
Error message
expected same number of event lists as transactions, received {} event lists and {} transactions What it means
In the same view-conversion code, after checking transaction_infos, the library verifies that the optional `events` field contains one event list per transaction. A `TransactionsWithProof` whose event_lists count differs from the transaction count cannot prove which events belong to which transaction, so the library rejects it rather than silently mis-associating events.
Source
Thrown at json-rpc/types/src/views.rs:885
return Ok(Self::empty());
}
let start_version = txs
.first_transaction_version
.ok_or_else(|| format_err!("expected a start version since tx list non-empty"))?;
let transactions = txs.transactions;
let transaction_infos = txs.proof.transaction_infos;
ensure!(
transaction_infos.len() == transactions.len(),
"expected same number of transaction_infos as transactions, \
received {} transaction_infos and {} transactions",
transaction_infos.len(),
transactions.len(),
);
let event_lists = if let Some(event_lists) = txs.events {
ensure!(
event_lists.len() == transactions.len(),
"expected same number of event lists as transactions, \
received {} event lists and {} transactions",
event_lists.len(),
transactions.len(),
);
event_lists
} else {
vec![Vec::new(); transactions.len()]
};
let tx_iter = transactions.into_iter();
let infos_iter = transaction_infos.into_iter();
let event_lists_iter = event_lists.into_iter();
let iter = tx_iter.enumerate().zip(infos_iter).zip(event_lists_iter);
let tx_list = iterView on GitHub (pinned to fc4714a8ea)
Solutions
- Compare `events.as_ref().map(|e| e.len())` with `transactions.len()` before conversion and re-fetch if they differ
- Re-query the node for transactions with proof and events; the response is incomplete or corrupt
- If events are unnecessary, pass `None` (or use the non-events query variant) instead of a partially populated event list
- When building fixtures, generate event_lists from the same loop that generates transactions so counts always match
- Upgrade client/node to matching versions if the events proof format changed
Example fix
// before
let txs = TransactionsWithProof { transactions, events: Some(event_lists), proof };
let view = txs.try_into()?;
// after
if let Some(ev) = &event_lists {
assert_eq!(ev.len(), transactions.len(), "event list count mismatch; re-fetch");
}
let txs = TransactionsWithProof { transactions, events: Some(event_lists), proof };
let view = txs.try_into()?; Defensive patterns
Strategy: validation
Validate before calling
fn validate_events(txs: &TransactionsWithProof) -> Result<(), String> {
if let Some(ev) = &txs.events {
if ev.len() != txs.transactions.len() {
return Err(format!("event lists ({}) != transactions ({})", ev.len(), txs.transactions.len()));
}
}
Ok(())
} Type guard
fn has_matching_event_lists(txs: &TransactionsWithProof) -> bool {
match &txs.events {
Some(ev) => ev.len() == txs.transactions.len(),
None => true,
}
} Try / catch
match tx_view.try_into_transaction_with_proof() {
Ok(verified) => verified,
Err(e) if e.to_string().contains("expected same number of event lists") => {
eprintln!("event list count mismatch, re-fetching");
re_fetch_with_events()? // returns the verified type
}
Err(e) => return Err(e.into()),
} Prevention
- Only populate `events` when the query actually requested events for all returned transactions
- Pass None instead of a partially filled event list when events are not needed
- Validate event list count against transaction count right after receiving the node response
- Keep client SDK and node versions aligned to avoid events format drift
When it happens
Trigger: Converting a `TransactionsWithProof` into the verified view when `txs.events` is `Some` but `event_lists.len() != transactions.len()` — e.g. a node response where events were truncated, or a manually built struct that attached events for only some transactions.
Common situations: Node bug or partially synced state returning event lists for a subset of transactions; protocol-version mismatch between client and server changing how events are batched; hand-written test data where events were populated for fewer/more entries than transactions.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- expected same number of transaction_infos as transactions, r
- [json-rpc] failed to create runtime
- Could not convert {0} to string
- Client#{0} is closed
- Received disconnect request message from client
AI-assisted analysis of diem/diem@fc4714a8ea (2026-09-04).
Data as JSON: /api/errors/98f1207674c98fba.
Report an issue: GitHub.