nautechsystems/nautilus_trader · error

Continuous future last_post_instrument_id {instrument_id} wa

Error message

Continuous future last_post_instrument_id {instrument_id} was not found in transitions

What it means

The optional `last_post_instrument_id` chain bound supplied with a continuous-future bar request/subscription does not match the `post_instrument_id` of any transition row. The library requires every explicit chain endpoint to exist in the parsed transitions table.

Source

Thrown at crates/data/src/engine/requests.rs:417

        anyhow::bail!("Continuous future transitions must not be empty");
    }

    if let Some(instrument_id) = first_pre_instrument_id
        && !transitions
            .iter()
            .any(|row| row.pre_instrument_id == instrument_id)
    {
        anyhow::bail!(
            "Continuous future first_pre_instrument_id {instrument_id} was not found in transitions"
        );
    }

    if let Some(instrument_id) = last_post_instrument_id
        && !transitions
            .iter()
            .any(|row| row.post_instrument_id == instrument_id)
    {
        anyhow::bail!(
            "Continuous future last_post_instrument_id {instrument_id} was not found in transitions"
        );
    }

    Ok(ContinuousFutureRequest {
        primary_bar_type,
        request_bar_aggregation: RequestBarAggregation {
            bar_types,
            update_subscriptions: false,
            // Roll gaps and weekends must not emit synthetic last-close bars (v1 parity)
            disable_build_with_no_updates: true,
            skip_first_non_full_bar: None,
        },
        transitions,
        adjustment_mode,
        first_pre_instrument_id,
        last_post_instrument_id,
    })

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Set `last_post_instrument_id` to exactly the `post_instrument_id` of the last transition row.
  2. Omit `last_post_instrument_id` so the series runs through the final available transition.
  3. Update the transitions data to include a roll into the requested ending contract.
  4. Verify you used the post-side (not pre-side) contract ID.

Example fix

// before
"last_post_instrument_id": "ESH6-CME"  // not yet in roll table
// after
"last_post_instrument_id": "ESZ5-CME"  // post_instrument_id of last transition
Defensive patterns

Strategy: validation

Validate before calling

if let Some(bound) = &params.last_post_instrument_id {
    assert!(transitions.iter().any(|t| &t.post_instrument_id == bound),
        "last_post_instrument_id {bound} not in transitions");
}

Type guard

fn post_bound_in_transitions(bound: &InstrumentId, transitions: &[Transition]) -> bool {
    transitions.iter().any(|t| t.post_instrument_id == *bound)
}

Prevention

When it happens

Trigger: Calling continuous_future_request_from_bars or continuous_future_subscription_from_bars with a `last_post_instrument_id` request parameter that matches no row's `post_instrument_id` in the `transitions` parameter.

Common situations: Specifying a future contract that has not yet been added as a transition (e.g. next quarter's expiry not yet in the roll table); typo or wrong symbol format; passing a pre-side ID where a post-side ID is required; stale bound after the roll schedule changed.

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/b89c92c788a0f749. Report an issue: GitHub.