nautechsystems/nautilus_trader · error
Coinbase fill has unknown order side
Error message
Coinbase fill has unknown order side
What it means
Coinbase fill reports carry an order side that is mapped to Nautilus OrderSide. If Coinbase reports the side as Unknown (missing/unexpected value in the fill payload), parse_order_side refuses to guess and returns this error, since a fill without a valid side cannot be applied to a position.
Source
Thrown at crates/adapters/coinbase/src/http/parse.rs:501
/// Converts a Coinbase order side to the Nautilus [`Option<OrderSide>`].
pub fn parse_order_side_optional(side: &CoinbaseOrderSide) -> Option<OrderSide> {
match side {
CoinbaseOrderSide::Buy => Some(OrderSide::Buy),
CoinbaseOrderSide::Sell => Some(OrderSide::Sell),
CoinbaseOrderSide::Unknown => None,
}
}
/// Converts a Coinbase order side to a Nautilus [`OrderSide`].
///
/// # Errors
///
/// Returns an error when Coinbase supplies an unknown side.
pub fn parse_order_side(side: &CoinbaseOrderSide) -> anyhow::Result<OrderSide> {
match side {
CoinbaseOrderSide::Buy => Ok(OrderSide::Buy),
CoinbaseOrderSide::Sell => Ok(OrderSide::Sell),
CoinbaseOrderSide::Unknown => anyhow::bail!("Coinbase fill has unknown order side"),
}
}
/// Converts a Coinbase order status to the Nautilus [`OrderStatus`].
///
/// `Pending` and `Queued` are transient pre-`Open` states the venue passes
/// through after acknowledging the order. They are mapped to `Accepted`
/// (rather than `Submitted`) so user-channel updates that race the REST
/// `OrderAccepted` event do not appear as a backwards transition to the
/// reconciler. `Open` also maps to `Accepted` because Nautilus differentiates
/// the initial accept event from later partial-fill states; callers should
/// promote the status to `PartiallyFilled` / `Filled` based on `filled_qty`.
pub fn parse_order_status(status: CoinbaseOrderStatus) -> OrderStatus {
match status {
CoinbaseOrderStatus::Pending | CoinbaseOrderStatus::Queued | CoinbaseOrderStatus::Open => {
OrderStatus::Accepted
}
CoinbaseOrderStatus::Filled => OrderStatus::Filled,View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw fill payload from Coinbase to see what side value was returned
- Update the CoinbaseOrderSide deserializer if Coinbase changed its side representation
- Drop or quarantine fills with Unknown side instead of feeding them into position accounting
Example fix
// before
let side = parse_order_side(&fill.side)?;
// after
let Ok(side) = parse_order_side(&fill.side) else { log::warn!("skipping fill with unknown side"); continue; }; Defensive patterns
Strategy: try-catch
Validate before calling
if fill.side == CoinbaseOrderSide::Unknown { return Err("fill side missing".into()); } Type guard
fn known_side(s: &CoinbaseOrderSide) -> Option<OrderSide> {
parse_order_side(s).ok()
} Try / catch
let side = match parse_order_side(&fill.side) {
Ok(s) => s,
Err(e) => { log::warn!("drop fill {}: {e}", fill.fill_id); continue; }
}; Prevention
- Log raw fill payloads to detect Coinbase schema changes early
- Pin and monitor adapter versions against Coinbase API changelog
- Skip rather than panic on malformed fills in reconciliation loops
When it happens
Trigger: parse_fill_report processing a Coinbase fill JSON whose side field is absent or an unrecognized value, deserializing to CoinbaseOrderSide::Unknown.
Common situations: Coinbase API schema changes or partial fill records with missing side; proxy/CDN mangling responses; processing historical fills from an API version with different side casing.
Understand the failure class
Background: "invalid response format", "malformed payload", "missing data field": when an API returns 200 but the response shape is wrong — this error's family across 23 libraries.
Related errors
- Skipping non-trade execution: {:?}
- Skipping execution without side: {:?}
- Unknown product type for '{product_id}'
- Failed to create price from fill px: {e}
- Failed to create quantity from fill sz: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/ff631039338ced07.
Report an issue: GitHub.