{"record":{"id":"f66d92bb42b0cfd0","repo":"nautechsystems/nautilus_trader","slug":"market-book-size-must-be-non-negative","errorCode":null,"errorMessage":"market-book size must be non-negative","messagePattern":"market-book size must be non-negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/parse.rs","lineNumber":763,"sourceCode":"    amount: Decimal,\n    side: PolymarketOrderSide,\n) -> anyhow::Result<MarketPriceResult> {\n    if book_levels.is_empty() {\n        anyhow::bail!(\"Empty order book: no liquidity available for market order\");\n    }\n\n    // Parse and sort levels deterministically so we never depend on API ordering.\n    // BUY: asks ascending (best/lowest first). SELL: bids descending (best/highest first).\n    anyhow::ensure!(amount > Decimal::ZERO, \"market amount must be positive\");\n    let mut parsed_levels = Vec::with_capacity(book_levels.len());\n    for level in book_levels {\n        let price = parse_decimal_exact(&level.price).context(\"invalid market-book price\")?;\n        let size = parse_decimal_exact(&level.size).context(\"invalid market-book size\")?;\n        anyhow::ensure!(\n            price > Decimal::ZERO && price < Decimal::ONE,\n            InvalidMarketPriceError(\"market-book price must be in (0, 1)\".to_string())\n        );\n        anyhow::ensure!(\n            size >= Decimal::ZERO,\n            \"market-book size must be non-negative\"\n        );\n\n        if !size.is_zero() {\n            parsed_levels.push((price, size));\n        }\n    }\n\n    if parsed_levels.is_empty() {\n        anyhow::bail!(\"Empty order book: no valid price levels for market order\");\n    }\n\n    match side {\n        PolymarketOrderSide::Buy => parsed_levels.sort_by_key(|a| a.0),\n        PolymarketOrderSide::Sell => parsed_levels.sort_by_key(|b| std::cmp::Reverse(b.0)),\n    }\n","sourceCodeStart":745,"sourceCodeEnd":781,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/parse.rs#L745-L781","documentation":"calculate_market_price requires every book level size to be non-negative. A negative size is impossible in a real order book and indicates corrupt venue data, so the level is rejected with this ensure! guard instead of corrupting the liquidity walk.","triggerScenarios":"A market-book response passed to calculate_market_price contains a level whose parsed size is negative — e.g. a malformed API payload, a diff/update applied in the wrong order, or a sign-convention bug in a local book builder.","commonSituations":"Applying book deltas without handling deletions, leaving negative residuals; buggy caching of book state; venue API incidents returning invalid payloads.","solutions":["Dump the raw book response and find the level with the negative size to locate the corruption source.","Fix the book maintenance code so level updates/deletions can never leave negative sizes.","Skip or drop non-negative-violating levels and rebuild the snapshot from a fresh REST fetch."],"exampleFix":"// before\nlevels.push(Level { size: delta_size, .. }); // delta can be negative\n// after\nlet new_size = existing.size + delta_size;\nanyhow::ensure!(new_size >= Decimal::ZERO);\nlevels.push(Level { size: new_size, .. });","handlingStrategy":"validation","validationCode":"if levels.iter().any(|l| Decimal::from_str(&l.size).map(|s| s < Decimal::ZERO).unwrap_or(true)) {\n    return Err(anyhow!(\"book contains negative sizes\"));\n}","typeGuard":"fn has_non_negative_sizes(levels: &[Level]) -> bool {\n    levels.iter().all(|l| Decimal::from_str(&l.size).map(|s| s >= Decimal::ZERO).unwrap_or(false))\n}","tryCatchPattern":null,"preventionTips":["Rebuild book state from fresh snapshots after anomalies","Never let delta application leave negative level sizes","Validate API payloads before applying them to local state"],"tags":["rust","order-book","validation","polymarket"],"backgroundTag":"invalid-argument-value","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}