nautechsystems/nautilus_trader · error

Swap event data is too short

Error message

Swap event data is too short

What it means

parse_swap_event_hypersync validates that the log's data holds at least 5 words of 32 bytes (amount0, amount1, sqrtPriceX96, liquidity, tick) before decoding a Uniswap V3 SwapEventData. Shorter data means the log cannot be a V3 Swap event, so the parser bails immediately.

Source

Thrown at crates/adapters/blockchain/src/exchanges/parsing/uniswap_v3/swap.rs:68

/// # Errors
///
/// Returns an error if the log parsing fails or if the event data is invalid.
///
/// # Panics
///
/// Panics if the contract address is not set in the log.
pub fn parse_swap_event_hypersync(dex: SharedDex, log: &HypersyncLog) -> anyhow::Result<SwapEvent> {
    validate_event_signature_hash("SwapEvent", SWAP_EVENT_SIGNATURE_HASH, log)?;

    let sender = extract_address_from_topic(log, 1, "sender")?;
    let recipient = extract_address_from_topic(log, 2, "recipient")?;

    if let Some(data) = &log.data {
        let data_bytes = data.as_ref();

        // Validate if data contains 5 parameters of 32 bytes each
        if data_bytes.len() < 5 * 32 {
            anyhow::bail!("Swap event data is too short");
        }

        // Decode the data using the SwapEventData struct
        let decoded = match <SwapEventData as SolType>::abi_decode(data_bytes) {
            Ok(decoded) => decoded,
            Err(e) => anyhow::bail!("Failed to decode swap event data: {e}"),
        };
        let _ = decoded.amount0;
        let pool_address = Address::from_slice(
            log.address
                .clone()
                .expect("Contract address should be set in logs")
                .as_ref(),
        );
        let pool_identifier = PoolIdentifier::Address(Ustr::from(&pool_address.to_string()));
        Ok(SwapEvent::new(
            dex,
            pool_identifier,

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Ensure the query filters by the exact V3 Swap topic0 signature
  2. Check data length >= 160 in the caller before calling the parser and skip short logs
  3. Verify you are decoding V3 pool logs, not V2/fork contracts
  4. Inspect the raw log data length returned by hypersync for the affected blocks

Example fix

// before
if data_bytes.len() < 5 * 32 {
    anyhow::bail!("Swap event data is too short");
}
// after
if data_bytes.len() < 5 * 32 {
    tracing::debug!(len = data_bytes.len(), "skipping non-V3 swap log (data too short)");
    return Ok(None); // or continue
}
Defensive patterns

Strategy: validation

Validate before calling

fn is_v3_swap_data_len(log: &Log) -> bool {
    log.data.as_ref().map(|d| d.as_ref().len() >= 160).unwrap_or(false)
}
if !is_v3_swap_data_len(&log) { skip_or_log(); }

Try / catch

match parse_swap_event_hypersync(&dex, &log) {
    Ok(ev) => handle(ev),
    Err(e) => { tracing::warn!(%e, "swap log skipped"); continue; }
}

Prevention

When it happens

Trigger: Calling parse_swap_event_hypersync with a log whose data is under 160 bytes — e.g. the subscription matched a V2 Swap (data holds only amounts), a non-V3 contract, or a truncated payload.

Common situations: Backfilling across a hard fork or chain where Swap layout differs; mixing V2 and V3 pool logs in one subscription; hypersync returning partial data for very old blocks.

Understand the failure class

Background: payload too large / request exceeds maximum size: why libraries cap bytes and how to fix oversize payloads — this error's family across 50 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/b9b632237ae75e36. Report an issue: GitHub.