nautechsystems/nautilus_trader · error · anyhow::Error

Binance Futures position request has unresolved instrument {

Error message

Binance Futures position request has unresolved instrument {instrument_id}

What it means

This error is raised by the Binance Futures execution client when a position status request references an instrument_id that is not resolvable to a Binance symbol (not in the execution cache and not in scope). Before building the positionRisk request the adapter checks whether the instrument is out of scope; if it is not out of scope but also has no usable mapping, it bails instead of sending a malformed request. It prevents submitting a request with an empty/invalid symbol.

Source

Thrown at crates/adapters/binance/src/futures/execution.rs:2613

    }

    async fn generate_position_status_reports(
        &self,
        cmd: &GeneratePositionStatusReports,
    ) -> anyhow::Result<Vec<PositionStatusReport>> {
        if let Some(instrument_id) = cmd.instrument_id
            && self
                .http_client
                .instrument_reconciliation(&instrument_id)
                .is_none()
        {
            if self.is_instrument_out_of_scope(instrument_id) {
                log::debug!(
                    "Dropping out-of-scope Binance Futures position request for instrument {instrument_id}"
                );
                return Ok(Vec::new());
            }
            anyhow::bail!(
                "Binance Futures position request has unresolved instrument {instrument_id}"
            );
        }
        let symbol = cmd.instrument_id.map(|id| format_binance_symbol(&id));

        let mut builder = BinancePositionRiskParamsBuilder::default();

        if let Some(s) = symbol {
            builder.symbol(s);
        }
        let params = builder.build().map_err(|e| anyhow::anyhow!("{e}"))?;

        let positions = self.http_client.query_positions(&params).await?;

        let mut reports = Vec::new();
        let mut position_reports_failed = 0usize;

        for position in positions {

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Add the instrument definition for the instrument_id before issuing the request so it resolves in the cache
  2. Verify the instrument_id venue matches the Binance Futures venue (not spot/USDT-M vs COIN-M mismatch)
  3. Check the out-of-scope config: the check log says out-of-scope instruments are dropped with Ok, so if you hit the bail the ID is 'known' but unresolvable — reinitialize or refresh the instrument cache
  4. Log the instrument_id and confirm it matches the instrument exactly as added (case and venue)

Example fix

// before
let reports = client.generate_position_status_reports(Some(instrument_id_from_config))
// after
assert!(client.is_instrument_cached(instrument_id_from_config), "add instrument first");
let reports = client.generate_position_status_reports(Some(instrument_id_from_config))
Defensive patterns

Strategy: validation

Validate before calling

if !client.is_instrument_cached(instrument_id) { add_instrument_or_abort(instrument_id); }

Try / catch

match client.generate_position_status_reports(Some(id)) { Err(e) if e.to_string().contains("unresolved instrument") => warn_and_reconcile(), r => r }

Prevention

When it happens

Trigger: Calling generate_order_status_reports/generate_position_status_reports with an instrument_id that was never registered or whose Binance metadata is missing from the cache, e.g. querying positions for a freshly added symbol before the instrument was defined or after cache invalidation.

Common situations: Requesting position reports for an instrument defined only locally, using a wrong or stale instrument ID (wrong venue suffix), or running before instruments were warmed up in the cache.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/d2fe041c664d19a4. Report an issue: GitHub.