tracel-ai/burn · error

AsyncPolicy should receive queued actions.

Error message

AsyncPolicy should receive queued actions.

What it means

After queueing an ActionMessage, AsyncPolicy::action blocks on action_receiver.recv() and panics on Err, which occurs when the reply Sender was dropped without sending a value. The autobatcher sends exactly one reply per item in flush_actions, so Err means that flush never happened: the server thread died (panic or loop exit) before this item was batched and processed.

Source

Thrown at crates/burn-rl/src/policy/async_policy.rs:293

    }

    fn action(
        &mut self,
        states: Self::Observation,
        deterministic: bool,
    ) -> (Self::Action, Vec<Self::ActionContext>) {
        let (action_sender, action_receiver) = std::sync::mpsc::channel();
        let item = ActionItem {
            sender: action_sender,
            inference_state: states,
            deterministic,
        };
        self.inference_state_sender
            .send(InferenceMessage::ActionMessage(item))
            .expect("should be able to send message to inference_server.");
        let action = action_receiver
            .recv()
            .expect("AsyncPolicy should receive queued actions.");
        (action.action, action.context)
    }

    fn update(&mut self, update: Self::PolicyState) {
        self.inference_state_sender
            .send(InferenceMessage::PolicyUpdate(update))
            .expect("AsyncPolicy should be able to send policy state.")
    }

    fn state(&self) -> Self::PolicyState {
        let (sender, receiver) = mpsc::channel();
        self.inference_state_sender
            .send(InferenceMessage::PolicyRequest(sender))
            .expect("should be able to send message to inference_server.");
        receiver
            .recv()
            .expect("AsyncPolicy should be able to receive policy state.")
    }

View on GitHub (pinned to d16f7ba2ed)

Solutions

  1. Diagnose the root cause of the server-thread death from logs; this panic is a symptom, not the cause.
  2. Keep increment_agents/decrement_agents counts in sync with live agents so batches always flush and requests never hang until shutdown.
  3. Make the server flush or reject pending items gracefully on shutdown so waiting callers get a real error instead of a dropped channel.
  4. Use recv_timeout with a descriptive panic/error on the caller side to distinguish 'server dead' from 'slow inference'.

Example fix

// before
let action = action_receiver
    .recv()
    .expect("AsyncPolicy should receive queued actions.");
// after
let action = action_receiver
    .recv_timeout(std::time::Duration::from_secs(60))
    .unwrap_or_else(|err| panic!("No action returned by inference server (thread dead or batch stalled): {}", err));
Defensive patterns

Strategy: retry

Validate before calling

// Ensure agent accounting is consistent before requesting actions
assert!(registered_agents.load(Ordering::Relaxed) > 0, "agents not registered; action batch may never flush");

Try / catch

match action_receiver.recv_timeout(Duration::from_secs(60)) {
    Ok(ac) => (ac.action, ac.context),
    Err(RecvTimeoutError::Timeout) => return Err(anyhow::anyhow!("action request stalled; batch never flushed")),
    Err(RecvTimeoutError::Disconnected) => return Err(anyhow::anyhow!("inference server died before returning an action")),
}

Prevention

When it happens

Trigger: An earlier panic in the autobatcher thread (failed reply send to another agent, or inner_policy.action panicking on the batched input such as a device/shape error) dropping all queued senders; or the thread exiting its loop so queued ActionItems are never flushed and their senders are dropped at teardown.

Common situations: One agent aborting its request (dropping its receiver) panics flush_actions' reply send, killing the thread and turning every other waiting agent's recv into this panic; num_agents accounting bugs causing batches that never reach the flush threshold, later compounded by a thread shutdown.

Related errors


AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05). Data as JSON: /api/errors/ff2a5cc6c2b905ce. Report an issue: GitHub.