{"record":{"id":"28fb1cb0ab315e44","repo":"nautechsystems/nautilus_trader","slug":"unmapped-in-scope-position-instrument-instrument","errorCode":null,"errorMessage":"unmapped in-scope position instrument {instrument_id}; {hint}","messagePattern":"unmapped in-scope position instrument (.+?); (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/polymarket/src/execution/reconciliation.rs","lineNumber":1492,"sourceCode":"    let instrument_id = instrument_id_from_market_token(&position.condition_id, &position.asset);\n\n    if instrument_filter\n        .is_some_and(|filter_id| !polymarket_instrument_ids_equivalent(filter_id, instrument_id))\n    {\n        return Ok(None);\n    }\n\n    if !instrument_in_load_ids_scope(instrument_id, collection_load_ids) {\n        log::debug!(\"Dropping out-of-scope position instrument {instrument_id}\");\n        return Ok(None);\n    }\n\n    if position_is_dust(position) {\n        return Ok(None);\n    }\n\n    if !position_instrument_loaded(&position.asset, instrument_id, instruments) {\n        anyhow::bail!(unmapped_in_scope_message(\n            \"position\",\n            instrument_id,\n            None,\n            collection_load_ids,\n        ));\n    }\n\n    Ok(build_position_report_from_reportable_position(\n        position, account_id, ts,\n    ))\n}\n\n/// Full reconciliation mass status generation.\n#[expect(clippy::too_many_arguments)]\npub(crate) async fn generate_mass_status(\n    http_client: &PolymarketClobHttpClient,\n    data_api_client: &PolymarketDataApiHttpClient,\n    instruments: &AtomicMap<Ustr, InstrumentAny>,","sourceCodeStart":1474,"sourceCodeEnd":1510,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/polymarket/src/execution/reconciliation.rs#L1474-L1510","documentation":"When converting a Data API position into a report, a non-dust position's instrument (derived from position.asset) is not present in the loaded instrument set even though it is within the collection's load-ids scope. The adapter bails because silently dropping a live position during reconciliation would understate the account's state.","triggerScenarios":"Position reconciliation encounters a position whose token (position.asset) maps to an instrument_id not loaded, and position_instrument_loaded fails while the instrument is in scope per collection_load_ids; dust positions (position_is_dust) return Ok(None) instead and never trigger this.","commonSituations":"Configured instrument list missing a market the wallet holds positions in; token ids changed after a market resolution/migration; loading instruments only for a subset of markets while the wallet still holds older positions.","solutions":["Add the missing market/instrument for the position's token to the configured instruments and reload.","Run instrument loading covering all tokens present in the wallet's positions before reconciliation.","Confirm the position's token id (position.asset) is current for that market on Polymarket.","If the position is intentionally irrelevant, verify position_is_dust thresholds are correctly configured rather than bypassing the check."],"exampleFix":"// before: reconciling positions against a partial instrument set\nlet reports = reconcile_positions(&positions, &instruments)?;\n// after: ensure every non-dust position token has a loaded instrument\nfor p in positions.iter().filter(|p| !position_is_dust(p)) {\n    instruments.ensure_loaded_for_token(&p.asset)?;\n}\nlet reports = reconcile_positions(&positions, &instruments)?;","handlingStrategy":"validation","validationCode":"// Rust: verify each non-dust position token is loaded before position reconciliation\nfn positions_covered(positions: &[Position], instruments: &InstrumentMap) -> bool {\n    positions.iter().filter(|p| !position_is_dust(p)).all(|p| instruments.contains_token(&p.asset))\n}\nassert!(positions_covered(&positions, &instruments));","typeGuard":"fn loaded_instrument<'a>(instruments: &'a InstrumentMap, token: &str) -> Option<&'a Instrument> {\n    instruments.by_token(token)\n}","tryCatchPattern":null,"preventionTips":["Derive the instrument load list from the wallet's actual positions, not a hand-maintained list.","Periodically re-sync instruments with gamma metadata to catch changed token ids.","Treat any unknown token in a wallet snapshot as a config gap to fix, not dust to ignore."],"tags":["polymarket","reconciliation","instrument-mapping","rust"],"backgroundTag":"entity-not-found","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"}