nautechsystems/nautilus_trader · error

OpenPositions: instrument not in cache for pair {}

Error message

OpenPositions: instrument not in cache for pair {}

What it means

When parsing Kraken's OpenPositions response into `PositionStatusReport`s, each position's raw pair string (e.g. "XBTUSD") must be mapped to a cached Nautilus instrument. If `get_instrument_by_raw_symbol` returns `None`, the adapter cannot determine precision/side metadata and fails with this error. It indicates the local instrument cache does not contain the venue pair returned by Kraken.

Source

Thrown at crates/adapters/kraken/src/http/spot/client.rs:2406

                && pair.as_str() != pos.pair
            {
                continue;
            }

            if let Some(status) = pos.posstatus.as_deref()
                && status != "open"
            {
                log::debug!(
                    "Skipping non-open OpenPositions entry for {}: posstatus={status}",
                    pos.pair,
                );
                continue;
            }

            let instrument = self
                .get_instrument_by_raw_symbol(pos.pair.as_str())
                .ok_or_else(|| {
                    anyhow::anyhow!(
                        "OpenPositions: instrument not in cache for pair {}",
                        pos.pair
                    )
                })?;

            let vol = Decimal::from_str_exact(&pos.vol)
                .with_context(|| format!("OpenPositions: failed to parse vol for {}", pos.pair))?;
            let vol_closed = Decimal::from_str_exact(&pos.vol_closed).with_context(|| {
                format!("OpenPositions: failed to parse vol_closed for {}", pos.pair)
            })?;

            let lot_net = (vol - vol_closed).max(Decimal::ZERO);
            let signed_lot = match pos.side {
                KrakenOrderSide::Buy => lot_net,
                KrakenOrderSide::Sell => -lot_net,
            };

            let entry = agg

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Load/refresh instruments for the account's pairs before calling OpenPositions (initialize the instruments provider).
  2. Remove or close positions on pairs you do not load, or widen instrument load filters to include all traded pairs.
  3. Check the raw pair string in the error and confirm it exists in Kraken's AssetPairs and in your instrument definitions.
  4. Update the adapter/cache data if the pair is new since your cached instruments snapshot.
Defensive patterns

Strategy: validation

Validate before calling

fn pair_cached(client: &KrakenSpotHttpClient, pair: &str) -> bool {
    client.get_instrument_by_raw_symbol(pair).is_some()
}

Try / catch

if !pair_cached(&client, "XBTUSD") { client.load_instruments_if_needed().await?; }

When it happens

Trigger: Calling the OpenPositions request when the instrument cache was never initialized (instruments provider not loaded), or Kraken returns a pair not present in the loaded instruments (delisted/new pair, different pair naming, or cache loaded for a filtered subset of pairs).

Common situations: Requesting position reports before `initialize`/instrument loading completed; account holds a margin position in a pair excluded from configured instrument filters; Kraken added a new pair not yet in the adapter's cached data.

Understand the failure class

Background: 'Could not be found', 'does not exist', 'not found in database': the resource-not-found family when an ID, slug, key, or URI lookup comes back empty — this error's family across 20 libraries.

Related errors


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