nautechsystems/nautilus_trader · error
Cannot determine fill quantity: fill_sz='{}' and acc_fill_sz
Error message
Cannot determine fill quantity: fill_sz='{}' and acc_fill_sz is None What it means
This variant fires when fill_sz has a value but acc_fill_sz is None. OKX normally sends both on fills; acc_fill_sz alone lets the parser use the cumulative total, and fill_sz alone is insufficient because the parser can't validate monotonicity against previous fills.
Source
Thrown at crates/adapters/okx/src/websocket/parse.rs:2141
let incremental = current_filled - prev_qty;
if incremental.is_zero() {
log::debug!(
"Skipping duplicate fill: acc_fill_sz='{acc_fill_sz}' unchanged from previous={prev_qty}"
);
return Ok(None);
}
incremental
} else {
// First fill, use accumulated as incremental
current_filled
}
} else {
anyhow::bail!(
"Cannot determine fill quantity: fill_sz is empty/zero and acc_fill_sz is empty/zero"
);
}
} else {
anyhow::bail!(
"Cannot determine fill quantity: fill_sz='{}' and acc_fill_sz is None",
msg.fill_sz
);
};
let fee_str = msg
.fee
.as_deref()
.filter(|fee| !fee.trim().is_empty())
.ok_or_else(|| anyhow::anyhow!("missing fee for fill report inst_id={}", msg.inst_id))?;
let fee_dec = Decimal::from_str(fee_str)
.map_err(|e| anyhow::anyhow!("Failed to parse fee '{fee_str}': {e}"))?;
let fee_currency = parse_fee_currency(msg.fee_ccy.as_str(), fee_dec, || {
format!("fill report for inst_id={}", msg.inst_id)
});
// OKX sends fees as negative numbers (e.g., "-2.5" for a $2.5 charge), parse_fee negates to positiveView on GitHub (pinned to 18893faf8b)
Solutions
- Verify the OKX orders channel payload includes acc_fill_sz and update any message-model/serde definitions that drop it
- If only incremental fill_sz is available, fall back to using fill_sz directly as the incremental quantity
- Check for field-name/serde renames (camelCase vs snake_case) after upgrading the adapter
Example fix
// before
struct OKXOrderMsg { fill_sz: Option<String> } // acc_fill_sz dropped
// after
struct OKXOrderMsg { fill_sz: Option<String>, acc_fill_sz: Option<String> } Defensive patterns
Strategy: type-guard
Validate before calling
if msg.acc_fill_sz.is_none() {
tracing::warn!("orders update missing acc_fill_sz; check API schema");
return Ok(None);
} Type guard
fn has_cumulative_fill(msg: &OKXOrderMsg) -> bool { msg.acc_fill_sz.is_some() } Try / catch
if !has_cumulative_fill(&msg) { /* fallback: use fill_sz incrementally or skip */ } Prevention
- Verify serde field mappings (acc_fill_sz) after adapter/API upgrades
- Keep OKX message models updated against current API docs
- Never strip fields when proxying OKX payloads through intermediaries
When it happens
Trigger: An orders-channel update carrying fill_sz but omitting acc_fill_sz entirely — typically an OKX API shape change, a different channel variant, or a hand-built message.
Common situations: OKX API version updates changing required fields; proxying messages through an intermediary that strips fields; incomplete test fixtures.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Missing sz for algo order {}
- Cannot determine spread fill quantity: fill_sz='{}' and acc_
- Cannot determine fill quantity: fill_sz is empty/zero and ac
- Unsupported algo order type: {:?}
- missing fee for spread fill report sprd_id={}; OKX sprd-orde
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/000147a13a38d111.
Report an issue: GitHub.