nautechsystems/nautilus_trader · error

Finalized Swap base amount {base_amount} is not a BUY output

Error message

Finalized Swap base amount {base_amount} is not a BUY output

What it means

For BUY orders the base token is the output of the swap, so the decoded base amount must be negative (output amounts are signed negatively in this event representation). If the base amount is not negative, the event does not represent a BUY-shaped swap for this pool, so the verification aborts instead of computing a wrong fill quantity.

Source

Thrown at crates/adapters/blockchain/src/execution/client.rs:4790

        } else {
            (event.amount1, event.amount0)
        };
    let last_qty = match plan.order.order_side() {
        OrderSide::Sell => {
            anyhow::ensure!(
                base_amount.is_positive() && base_amount.unsigned_abs() == plan.amount_in,
                "Finalized Swap input {base_amount} does not match the persisted amount {}",
                plan.amount_in
            );
            plan.order.quantity()
        }
        OrderSide::Buy => {
            anyhow::ensure!(
                quote_amount.is_positive() && quote_amount.unsigned_abs() == plan.amount_in,
                "Finalized Swap input {quote_amount} does not match the persisted amount {}",
                plan.amount_in
            );
            anyhow::ensure!(
                base_amount.is_negative(),
                "Finalized Swap base amount {base_amount} is not a BUY output"
            );
            raw_amount_to_quantity(
                base_amount.unsigned_abs(),
                plan.pool.get_base_token().decimals,
            )?
        }
    };

    let block = &included.finality.inclusion_header;
    anyhow::ensure!(
        block.number == included.block_number
            && block.hash == included.receipt.block_hash.to_string(),
        "Verified inclusion header {} does not match receipt hash {}",
        included.block_number,
        included.receipt.block_hash
    );

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the base/quote amount selection (swap the amount0/amount1 branch) if token ordering is misconfigured
  2. Verify the plan's order_side matches the actual submitted trade direction
  3. Check the DEX decoder's sign convention for output amounts and normalize it to the library's signed convention
  4. Re-derive the order side from amount signs in the event if the direction is ambiguous

Example fix

// before
anyhow::ensure!(base_amount.is_negative(), "...");
// after (if decoder emits unsigned outputs)
let base_signed = -Decimal::from(raw_base_output);
anyhow::ensure!(base_signed.is_negative(), "...");
Defensive patterns

Strategy: type-guard

Validate before calling

if order_side == OrderSide::Buy && !base_amount.is_negative() {
    return Err(anyhow!("BUY base output must be negative, got {}", base_amount));
}

Type guard

fn is_buy_output(base_amount: &Decimal) -> bool { base_amount.is_negative() }

Try / catch

let qty = if is_buy_output(&base_amount) {
    raw_amount_to_quantity(base_amount.unsigned_abs(), decimals)?
} else {
    return Err(anyhow!("unexpected sign for BUY output"));
};

Prevention

When it happens

Trigger: Verifying a BUY where the decoded base amount is zero or positive — typically because base/quote were swapped in the amount0/amount1 selection, the order side was mislabeled, or the decoder emits unsigned amounts for this DEX.

Common situations: Order side recorded as Buy but the actual trade direction was Sell (plan built from stale intent); pool token ordering mismatch between configuration and on-chain token0/token1; a DEX decoder that does not sign output amounts as this verification expects.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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