tracel-ai/burn · error
Autobatcher should be able to send resulting actions.
Error message
Autobatcher should be able to send resulting actions.
What it means
flush_actions sends each batched action back to its waiting agent via a oneshot sender and expects delivery to succeed. Panic means a receiver was already dropped — the agent went away before the policy flushed the batch.
Source
Thrown at crates/burn-rl/src/policy/async_policy.rs:96
let input: Vec<_> = self
.batch_action
.iter()
.map(|m| m.inference_state.clone())
.collect();
// Only deterministic if all actions are requested as deterministic.
let deterministic = self.batch_action.iter().all(|item| item.deterministic);
let (actions, context) = self
.inner_policy
.action(P::Observation::batch(input), deterministic);
let actions: Vec<_> = actions.unbatch();
for (i, item) in self.batch_action.iter().enumerate() {
item.sender
.send(ActionContext {
context: vec![context[i].clone()],
action: actions[i].clone(),
})
.expect("Autobatcher should be able to send resulting actions.");
}
self.batch_action.clear();
}
pub fn flush_logits(&mut self) {
if self.len_logits() == 0 {
return;
}
let input: Vec<_> = self
.batch_logits
.iter()
.map(|m| m.inference_state.clone())
.collect();
let output = self.inner_policy.forward(P::Observation::batch(input));
let logits: Vec<_> = output.unbatch();
for (i, item) in self.batch_logits.iter().enumerate() {
item.sender
.send(logits[i].clone())View on GitHub (pinned to d16f7ba2ed)
Solutions
- Ensure agents stay alive until flush_actions completes — don't drop their receivers mid-batch
- Drain/flush pending actions before decrementing agents or updating the policy
- Make agent shutdown cooperative: let it consume its action before terminating
- Replace expect with error handling to skip dead receivers instead of panicking
Example fix
// before
item.sender.send(ActionContext { ... })
.expect("Autobatcher should be able to send resulting actions.");
// after
if item.sender.send(ActionContext { ... }).is_err() {
// receiver dropped; skip this agent
} Defensive patterns
Strategy: try-catch
Validate before calling
// Before update_policy, confirm all batched agents still hold receivers
assert_eq!(self.batch_action.iter().filter(|i| i.sender.is_closed()).count(), 0,
"some agents dropped before flush_actions"); Try / catch
if let Err(e) = item.sender.send(ActionContext { context: vec![context[i].clone()], action: actions[i].clone() }) {
log::warn!("agent receiver dropped, skipping: {e}");
continue;
} Prevention
- Don't drop agent receivers mid-batch; use cooperative shutdown
- Flush pending actions before decrement_agents or policy updates
- Treat send errors as agent-loss, not a panic condition
When it happens
Trigger: An agent thread/context is dropped (decremented/aborted) after push_action queued its sender but before update_policy's flush_actions runs; then send() fails on the dead receiver.
Common situations: Aborting agent tasks mid-episode; panics in agent code dropping its receiver; calling decrement_agents while batched actions are still pending; race between policy update and agent teardown.
Related errors
- Autobatcher should be able to send resulting probabilities.
- Event store thread crashed: {err:?}
- Autobatcher should be able to send current policy state.
- Can send message to autobatcher.
- Should be able to send message to inference_server
AI-assisted analysis of tracel-ai/burn@d16f7ba2ed (2026-09-05).
Data as JSON: /api/errors/a22e7118f6076e51.
Report an issue: GitHub.