nautechsystems/nautilus_trader · error
unmapped in-scope position instrument {instrument_id}; {hint
Error message
unmapped in-scope position instrument {instrument_id}; {hint} What it means
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.
Source
Thrown at crates/adapters/polymarket/src/execution/reconciliation.rs:1492
let instrument_id = instrument_id_from_market_token(&position.condition_id, &position.asset);
if instrument_filter
.is_some_and(|filter_id| !polymarket_instrument_ids_equivalent(filter_id, instrument_id))
{
return Ok(None);
}
if !instrument_in_load_ids_scope(instrument_id, collection_load_ids) {
log::debug!("Dropping out-of-scope position instrument {instrument_id}");
return Ok(None);
}
if position_is_dust(position) {
return Ok(None);
}
if !position_instrument_loaded(&position.asset, instrument_id, instruments) {
anyhow::bail!(unmapped_in_scope_message(
"position",
instrument_id,
None,
collection_load_ids,
));
}
Ok(build_position_report_from_reportable_position(
position, account_id, ts,
))
}
/// Full reconciliation mass status generation.
#[expect(clippy::too_many_arguments)]
pub(crate) async fn generate_mass_status(
http_client: &PolymarketClobHttpClient,
data_api_client: &PolymarketDataApiHttpClient,
instruments: &AtomicMap<Ustr, InstrumentAny>,View on GitHub (pinned to 18893faf8b)
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.
Example fix
// before: reconciling positions against a partial instrument set
let reports = reconcile_positions(&positions, &instruments)?;
// after: ensure every non-dust position token has a loaded instrument
for p in positions.iter().filter(|p| !position_is_dust(p)) {
instruments.ensure_loaded_for_token(&p.asset)?;
}
let reports = reconcile_positions(&positions, &instruments)?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: verify each non-dust position token is loaded before position reconciliation
fn positions_covered(positions: &[Position], instruments: &InstrumentMap) -> bool {
positions.iter().filter(|p| !position_is_dust(p)).all(|p| instruments.contains_token(&p.asset))
}
assert!(positions_covered(&positions, &instruments)); Type guard
fn loaded_instrument<'a>(instruments: &'a InstrumentMap, token: &str) -> Option<&'a Instrument> {
instruments.by_token(token)
} Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.
Related errors
- unmapped in-scope open order instrument {instrument_id} (tok
- provider venue order {} is not owned by the account
- target order {venue_order_id} appears more than once in trad
- trade {} trader_side {:?} contradicts target order {venue_or
- provider maker order {} side {provider_side} contradicts der
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/28fb1cb0ab315e44.
Report an issue: GitHub.