{"record":{"id":"5f821271b9594254","repo":"nautechsystems/nautilus_trader","slug":"expected-polymarket-binaryoption-instrument-found","errorCode":null,"errorMessage":"expected Polymarket BinaryOption instrument, found {instrument:?}","messagePattern":"expected Polymarket BinaryOption instrument, found (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/reconciliation.rs","lineNumber":244,"sourceCode":"        .with_context(|| format!(\"maker trade {} has invalid trade ID source\", trade.id))?;\n    let composite_trade_id = composite_trade_id_value(&trade.id, &maker_order.order_id);\n    let trade_id = checked_trade_id(\n        &composite_trade_id,\n        &format!(\"maker trade {} composite\", trade.id),\n    )?;\n    Ok(ValidatedMakerReportIdentifiers {\n        venue_order_id,\n        trade_id,\n    })\n}\n\nfn validate_instrument_binding(\n    instrument: &InstrumentAny,\n    condition_id: &str,\n    outcome: PolymarketOutcome,\n) -> anyhow::Result<()> {\n    let InstrumentAny::BinaryOption(binary) = instrument else {\n        anyhow::bail!(\"expected Polymarket BinaryOption instrument, found {instrument:?}\");\n    };\n    let instrument_condition = binary\n        .info\n        .as_ref()\n        .and_then(|info| info.get_str(\"condition_id\"))\n        .context(\"Polymarket instrument is missing condition_id metadata\")?;\n\n    anyhow::ensure!(\n        instrument_condition.eq_ignore_ascii_case(condition_id),\n        \"provider condition {condition_id} does not match instrument condition {instrument_condition}\",\n    );\n    let instrument_outcome = binary\n        .outcome\n        .context(\"Polymarket instrument is missing outcome metadata\")?;\n    anyhow::ensure!(\n        instrument_outcome == outcome.as_str(),\n        \"provider outcome {outcome} does not match instrument outcome {instrument_outcome}\",\n    );","sourceCodeStart":226,"sourceCodeEnd":262,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/reconciliation.rs#L226-L262","documentation":"validate_instrument_binding expects the instrument bound to a Polymarket condition to be a BinaryOption whose metadata carries condition_id and outcome info; if the caller passes any other InstrumentAny variant, it bails with a debug dump of what was actually found. It is an internal binding/type contract check during order-report and trade reconciliation.","triggerScenarios":"Calling build_order_report_from_order, classify_target_trade, or build_fill_reports_from_trades with an instrument registered as a non-BinaryOption type (e.g. a generic equity or crypto perpetual) that is not a Polymarket binary market, or with an incorrectly-registered instrument.","commonSituations":"Registering instruments with the wrong factory during adapter setup; feeding orders/fills from another venue into the Polymarket reconciliation path; a version change where instrument construction defaults changed.","solutions":["Ensure the instrument for this condition_id was created as a Polymarket BinaryOption via the Polymarket instrument provider/factory.","Check that reconciliation inputs come from Polymarket order/fill events, not another adapter's instrument cache.","Log/inspect the instrument debug output in the message to see which variant was actually passed and where it originated.","Add an up-front assert or filter that only BinaryOption instruments reach the Polymarket reconciliation path."],"exampleFix":"// before\nlet report = build_order_report_from_order(&any_instrument, &order)?;\n// after\nif !matches!(any_instrument, InstrumentAny::BinaryOption(_)) {\n    eprintln!(\"skipping non-BinaryOption instrument in Polymarket reconciliation\");\n    return Ok(None);\n}\nlet report = build_order_report_from_order(&any_instrument, &order)?;","handlingStrategy":"type-guard","validationCode":"let InstrumentAny::BinaryOption(binary) = instrument else {\n    return Err(format!(\"Polymarket reconciliation requires BinaryOption, got {instrument:?}\"));\n};","typeGuard":"fn is_polymarket_binary(instrument: &InstrumentAny) -> bool {\n    matches!(instrument, InstrumentAny::BinaryOption(_))\n}","tryCatchPattern":null,"preventionTips":["Register instruments through the Polymarket provider so they are BinaryOption","Keep other venues' instruments out of the Polymarket reconciliation path","Check the instrument's condition_id metadata at registration time","Use matches!/let-else narrowing before any condition-specific logic"],"tags":["polymarket","type-mismatch","instrument","reconciliation"],"backgroundTag":"type-mismatch","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"}