nautechsystems/nautilus_trader · error · anyhow::Error

DEX '{dex_type}' on chain '{}' cannot be synced: missing a P

Error message

DEX '{dex_type}' on chain '{}' cannot be synced: missing a PoolCreated parser for pool discovery.

What it means

`run_sync_dex` syncs a DEX's pools by replaying PoolCreated events. Before starting, it checks `supports_pool_discovery()` on the registered DEX; if no PoolCreated parser is implemented for that DEX/chain, pool discovery is impossible and the sync is aborted with this bail instead of silently producing zero pools.

Source

Thrown at crates/cli/src/blockchain/sync.rs:60

        let supported_dexes = get_supported_dexes_for_chain(chain.name);
        if supported_dexes.is_empty() {
            anyhow::anyhow!("Invalid DEX name '{}' (case-insensitive). Chain '{}' is not supported for pool syncing.",dex, chain.name)
        } else {
            anyhow::anyhow!("Invalid DEX name '{}' (case-insensitive). Supported DEXes for chain '{}': {}",dex,chain.name,supported_dexes.join(", "))
        }
    })?;

    // Fail before connecting to the RPC/database when the DEX cannot discover pools from
    // PoolCreated logs; without a parser sync-dex would otherwise find zero pools silently.
    let dex_extended = get_dex_extended(chain.name, &dex_type).ok_or_else(|| {
        anyhow::anyhow!(
            "DEX '{dex_type}' is not registered on chain '{}'",
            chain.name
        )
    })?;

    if !dex_extended.supports_pool_discovery() {
        anyhow::bail!(
            "DEX '{dex_type}' on chain '{}' cannot be synced: missing a PoolCreated parser for pool discovery.",
            chain.name
        );
    }

    let postgres_connect_options = get_postgres_connect_options(
        database.host,
        database.port,
        database.username,
        database.password,
        database.database,
    );
    // Get RPC HTTP URL: CLI arg, Infura provider, OR RPC_HTTP_URL env var
    let rpc_http_url = rpc_url
        .or_else(|| check_infura_rpc_provider(&chain.name))
        .or_else(|| std::env::var("RPC_HTTP_URL").ok())
        .ok_or_else(|| {
            anyhow::anyhow!(

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Implement the PoolCreated parser for the DEX and register it so `supports_pool_discovery()` returns true
  2. Choose a different `--dex` value that already supports pool discovery
  3. Seed pools for that DEX by another means (manual registration/import) instead of event-based sync
  4. Verify the dex_type string matches a fully implemented integration

Example fix

// before
// no PoolCreated parser registered for DexKind::MyDex
// after
impl PoolCreatedParser for MyDexParser { /* decode PoolCreated event */ }
registry.register_parser(DexKind::MyDex, MyDexParser);
Defensive patterns

Strategy: validation

Validate before calling

if !dex_extended.supports_pool_discovery() {
    eprintln!("DEX {:?} has no PoolCreated parser; choose another DEX or implement the parser", dex_type);
}

Try / catch

match run_sync_dex(&chain, dex_type).await {
    Err(e) if e.to_string().contains("PoolCreated") => eprintln!("sync unsupported for this DEX: {e}"),
    other => other?,
}

Prevention

When it happens

Trigger: Calling `blockchain sync` (or `run_sync_dex` via `run_blockchain_command`) for a DEX type that is registered on the chain but lacks a PoolCreated event parser implementation.

Common situations: Adding a new DEX integration before implementing its discovery parser; typo'd or newly-added `dex_type` value mapped to a stub; a chain config that registers an unsupported DEX variant.

Related errors


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