nautechsystems/nautilus_trader · error
provider GTD order {} requires a valid positive expiration
Error message
provider GTD order {} requires a valid positive expiration What it means
When rebuilding an order report from a provider PolymarketOpenOrder, GTD (Good-Till-Date) orders must carry a parsable positive expiration timestamp. parse_provider_order_expiration returns Option<UnixNanos>; if the provider GTD order has no usable expiration, this anyhow error aborts validation in validate_order_row_values.
Source
Thrown at crates/adapters/polymarket/src/execution/reconciliation.rs:389
&format!("provider order {} matched quantity", order.id),
true,
)?;
validate_price_evidence(
order.price,
price_precision,
&format!("provider order {} price", order.id),
)?;
let ts_accepted = order
.created_at
.checked_mul(NANOSECONDS_IN_SECOND)
.with_context(|| {
format!(
"provider order {} created_at seconds {} overflow Unix nanoseconds",
order.id, order.created_at,
)
})?;
let expire_time = parse_provider_order_expiration(order)?;
anyhow::ensure!(
TimeInForce::from(order.order_type) != TimeInForce::Gtd || expire_time.is_some(),
"provider GTD order {} requires a valid positive expiration",
order.id,
);
Ok(ValidatedOrderRow {
venue_order_id: checked_venue_order_id(&order.id, "provider order")?,
ts_accepted: UnixNanos::from(ts_accepted),
expire_time,
})
}
fn validate_trade_values(
quantity: Decimal,
price: Decimal,
size_precision: u8,
quantity_field: &str,
price_field: &str,
) -> anyhow::Result<Price> {View on GitHub (pinned to 18893faf8b)
Solutions
- Re-fetch the order from the Polymarket API to obtain its expiration and refresh the cached provider order.
- If the order is genuinely not time-limited, correct its order_type to Gtc so the GTD check does not apply.
- Fix the persistence layer to store/populate expiration UnixNanos for GTD orders instead of null/0.
Example fix
// before let mut order = cached.clone(); // order_type: Gtd, expiration: None let report = build_order_report_from_order(&provider_order, &order)?; // after order.set_time_in_force(TimeInForce::Gtd(UnixNanos::from(expire_unix_secs))); // populate before build let report = build_order_report_from_order(&provider_order, &order)?;
Defensive patterns
Strategy: validation
Validate before calling
fn has_valid_gtd_expiration(order: &PolymarketOpenOrder) -> bool {
TimeInForce::from(order.order_type) != TimeInForce::Gtd
|| order.expiration.map(|e| e.as_u64() > 0).unwrap_or(false)
} Type guard
fn is_gtd_with_expiry(o: &PolymarketOpenOrder) -> Option<UnixNanos> {
if TimeInForce::from(o.order_type) == TimeInForce::Gtd { o.expiration.filter(|e| e.as_u64() > 0) } else { None }
} Try / catch
match build_order_report_from_order(&provider_order, &cached) {
Err(e) if e.to_string().contains("requires a valid positive expiration") => {
refresh_order_from_provider(&provider_order.id).await?; // re-fetch with expiration
}
other => other?,
} Prevention
- Always persist expiration UnixNanos for GTD orders in the local cache
- Re-fetch provider orders instead of trusting stale cached rows for GTD
- Validate TIF/expiration pairing when orders are first submitted, not only at reconciliation
When it happens
Trigger: build_order_report_from_order processes a provider order whose order_type maps to TimeInForce::Gtd but the expiration field is missing, zero, negative, or unparseable, so expire_time is None.
Common situations: Provider API responses omitting the expiration for legacy GTC/GTD orders; epoch timestamp of 0 treated as no expiration; orders imported before the adapter began persisting expire_time; stale local order cache rows with null expiration columns.
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
- provider order expiration seconds {provider_expire_seconds:?
- unmapped_in_scope_message("open order", instrument_id, Some(
- unmapped_in_scope_message("position", instrument_id, None, c
- expected Polymarket BinaryOption instrument, found {instrume
- provider venue order {} is not owned by the account
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/f9a452def1a25521.
Report an issue: GitHub.