{"record":{"id":"deabcd51fa5f7c44","repo":"nautechsystems/nautilus_trader","slug":"builder-fee-rate-must-be-non-negative","errorCode":null,"errorMessage":"builder fee rate must be non-negative","messagePattern":"builder fee rate must be non-negative","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/parse.rs","lineNumber":530,"sourceCode":"    price: Decimal,\n    fee_rate: Decimal,\n    fee_exponent: Decimal,\n    builder_taker_fee_rate: Decimal,\n) -> anyhow::Result<Decimal> {\n    if price <= Decimal::ZERO || price >= Decimal::ONE {\n        anyhow::bail!(\n            \"invalid market-buy price {price}: must satisfy 0 < price < 1 for fee adjustment\",\n        );\n    }\n\n    let platform_fee_rate = fee_curve_rate(fee_rate, price, fee_exponent)?;\n\n    anyhow::ensure!(amount > Decimal::ZERO, \"market-buy amount must be positive\");\n    anyhow::ensure!(\n        user_pusd_balance > Decimal::ZERO,\n        \"market-buy balance must be positive\"\n    );\n    anyhow::ensure!(\n        builder_taker_fee_rate >= Decimal::ZERO,\n        \"builder fee rate must be non-negative\"\n    );\n    let platform_fee = amount\n        .checked_div(price)\n        .and_then(|shares| shares.checked_mul(platform_fee_rate))\n        .context(\"market-buy platform fee overflow\")?;\n    let builder_fee = amount\n        .checked_mul(builder_taker_fee_rate)\n        .context(\"market-buy builder fee overflow\")?;\n    let total_cost = amount\n        .checked_add(platform_fee)\n        .and_then(|cost| cost.checked_add(builder_fee))\n        .context(\"market-buy total cost overflow\")?;\n\n    let raw = if user_pusd_balance <= total_cost {\n        let divisor = platform_fee_rate\n            .checked_div(price)","sourceCodeStart":512,"sourceCodeEnd":548,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/parse.rs#L512-L548","documentation":"adjust_market_buy_amount requires the builder taker fee rate to be non-negative, since it is used to compute the fee-inclusive total cost. A negative builder_taker_fee_rate is rejected with \"builder fee rate must be non-negative\".","triggerScenarios":"Calling adjust_market_buy_amount with a builder_taker_fee_rate < 0, usually sourced from a malformed fee configuration or a parse bug producing a signed decimal.","commonSituations":"Hand-edited config where the builder fee was entered as a negative number; confusion between rate directions (payer vs receiver) causing sign flips; unit mixups (basis points vs fraction) with minus signs.","solutions":["Set builder_taker_fee_rate to a non-negative decimal in the fee configuration.","Check the code path that parses the builder fee from the venue/config and clamp or reject negatives at parse time.","Confirm rate units and sign conventions for Polymarket builder fees."],"exampleFix":"// before\nlet builder_fee = Decimal::new(-10, 4); // negative\nadjust_market_buy_amount(amount, price, balance, builder_fee, ...)?;\n// after\nlet builder_fee = Decimal::new(10, 4); // 0.0010, non-negative\nadjust_market_buy_amount(amount, price, balance, builder_fee, ...)?;","handlingStrategy":"validation","validationCode":"if builder_taker_fee_rate < Decimal::ZERO { return Err(\"builder fee rate must be >= 0\".into()); }","typeGuard":"fn is_non_negative_rate(rate: Decimal) -> bool { rate >= Decimal::ZERO }","tryCatchPattern":null,"preventionTips":["Validate fee-rate config values (non-negative, sane range) at startup.","Reject negative rates at config parse time with a clear message.","Document fee-rate units to avoid sign/unit mixups."],"tags":["polymarket","fees","validation","config"],"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"}