nautechsystems/nautilus_trader · error
Failed to parse outcomes '{}': {e}
Error message
Failed to parse outcomes '{}': {e} What it means
parse_gamma_market parses the market's outcomes field, which Polymarket delivers as a stringified JSON array of strings. This error is thrown when that string cannot be deserialized into Vec<String> — malformed JSON, empty string, or a changed payload shape.
Source
Thrown at crates/adapters/polymarket/src/http/parse.rs:122
.events
.as_ref()?
.iter()
.find_map(|event| event.game_id.clone())
});
let token_ids: Vec<String> = serde_json::from_str(&market.clob_token_ids).map_err(|e| {
anyhow::anyhow!(
"Failed to parse clob_token_ids '{}': {e}",
market.clob_token_ids
)
})?;
if token_ids.len() != 2 {
anyhow::bail!("Expected 2 token IDs, received {}", token_ids.len());
}
let outcomes: Vec<String> = serde_json::from_str(&market.outcomes)
.map_err(|e| anyhow::anyhow!("Failed to parse outcomes '{}': {e}", market.outcomes))?;
if outcomes.len() != 2 {
anyhow::bail!("Expected 2 outcomes, received {}", outcomes.len());
}
let tick_size = market
.order_price_min_tick_size
.unwrap_or(DEFAULT_TICK_SIZE);
let price_precision = POLYMARKET_PRICE_PRECISION;
// Polymarket charges fees using `feeSchedule.rate` on the Gamma market.
// Only takers pay; makers are always zero.
// Reference: https://docs.polymarket.com/trading/fees
let maker_fee: Option<Decimal> = market.fee_schedule.as_ref().map(|_| Decimal::ZERO);
let taker_fee: Option<Decimal> = market.fee_schedule.as_ref().map(|fs| fs.rate);
let min_size = market.order_min_size;
View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the raw market.outcomes string to confirm the payload shape.
- Adapt the GammaMarket deserialization to accept both stringified and native-array forms.
- Skip or quarantine markets with unparseable outcomes instead of failing the whole batch.
Example fix
// before
let outcomes: Vec<String> = serde_json::from_str(&market.outcomes)
.map_err(|e| anyhow::anyhow!("Failed to parse outcomes '{}': {e}", market.outcomes))?;
// after
let outcomes: Vec<String> = serde_json::from_str(&market.outcomes)
.or_else(|_| serde_json::from_value(market.outcomes_value.clone()))
.map_err(|e| anyhow::anyhow!("Failed to parse outcomes '{}': {e}", market.outcomes))?; Defensive patterns
Strategy: validation
Validate before calling
fn has_stringified_outcomes(market: &GammaMarket) -> bool {
!market.outcomes.is_empty()
&& market.outcomes.starts_with('[')
&& serde_json::from_str::<Vec<String>>(&market.outcomes).is_ok()
} Type guard
fn parse_outcomes(raw: &str) -> Option<Vec<String>> {
serde_json::from_str::<Vec<String>>(raw).ok()
} Try / catch
let outcomes = match serde_json::from_str::<Vec<String>>(&market.outcomes) {
Ok(v) => v,
Err(e) => { warn!("skipping market {}: bad outcomes: {e}", market.id); return Ok(None); }
}; Prevention
- Keep test fixtures matching the real Gamma wire format (stringified arrays).
- Add a custom deserializer on GammaMarket fields tolerant of both string and array forms.
- Log raw payloads on parse failure to detect upstream schema drift quickly.
When it happens
Trigger: Calling parse_gamma_market (directly or via parse_markets_with_transient / request_instruments) on a market whose outcomes field is empty, invalid JSON, or not a string-encoded array.
Common situations: Gamma API schema drift (outcomes arriving as a native array), mocked responses that put real arrays in the field, or partially written/cached market records.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Failed to parse clob_token_ids '{}': {e}
- Expected 2 token IDs, received {}
- Expected 2 outcomes, received {}
- invalid signed E18 integer for {field}: {value}
- Empty book snapshot for {instrument_id}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/8065737f6aff8b6f.
Report an issue: GitHub.