nautechsystems/nautilus_trader · error

No active time-range pipeline for {parent_id}

Error message

No active time-range pipeline for {parent_id}

What it means

dispatch_next_time_range_pipeline_request looks up the parent's TimeRangePipelineState by parent_id; if no active pipeline is registered under that ID, the engine cannot produce the next child window and bails. It means the pipeline either never started, already completed and was removed, or the caller passed a stale/wrong UUID4.

Source

Thrown at crates/data/src/engine/time_range.rs:162

    fn time_range_pipeline_response_client_id(&mut self, req: &RequestCommand) -> ClientId {
        let request_client_id = req.client_id().copied();
        let venue = req.venue().copied();
        self.get_client(request_client_id.as_ref(), venue.as_ref())
            .map(|client| client.client_id())
            .or(request_client_id)
            .unwrap_or_else(|| ClientId::new("CATALOG"))
    }

    fn dispatch_next_time_range_pipeline_request(
        &mut self,
        parent_id: UUID4,
        data_received: Option<bool>,
    ) -> anyhow::Result<()> {
        let ts_init = self.clock.borrow().timestamp_ns();
        let child = {
            let Some(state) = self.time_range_pipeline_requests.get_mut(&parent_id) else {
                anyhow::bail!("No active time-range pipeline for {parent_id}");
            };

            state.generator.next_window(data_received).map(|window| {
                time_range_child_request(&state.parent, window.start_ns, window.end_ns, ts_init)
            })
        };
        let Some(child) = child else {
            self.emit_empty_time_range_pipeline_response(parent_id);
            return Ok(());
        };

        let child_id = *child.request_id();
        self.time_range_pipeline_parent_request_id
            .insert(child_id, parent_id);

        if let Err(e) = self.execute_request(child) {
            self.time_range_pipeline_parent_request_id.remove(&child_id);
            return Err(e);

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Always pass the parent request's UUID4, not the child's, when advancing the pipeline
  2. Guard against processing duplicate or late child responses after pipeline completion
  3. Log/track pipeline lifecycle so dispatch is only invoked while the pipeline is active

Example fix

// before
engine.dispatch_next_time_range_pipeline_request(child_id, Some(true))?;
// after
engine.dispatch_next_time_range_pipeline_request(parent_request_id, Some(true))?; // parent UUID4
Defensive patterns

Strategy: try-catch

Validate before calling

if !active_pipelines.contains_key(&parent_id) { return Err(anyhow!("pipeline {parent_id} not active")); }

Try / catch

match engine.dispatch_next_time_range_pipeline_request(parent_id, data_received) {
    Err(e) if e.to_string().contains("No active time-range pipeline") => {/* pipeline finished; ignore late callback */},
    other => other?,
}

Prevention

When it happens

Trigger: Calling dispatch_next_time_range_pipeline_request (directly or via handle_time_range_pipeline_child_response) with a parent_id that is not in self.time_range_pipeline_requests — e.g. after the pipeline finished and was cleaned up, or with a child request ID mistaken for the parent ID.

Common situations: Responding to a child request using the child's ID instead of the parent's; a duplicate/late child response arriving after the pipeline was removed; replaying recorded messages out of order across engine restarts.

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