nautechsystems/nautilus_trader · error
submit accepted
Error message
submit accepted
What it means
Test panic from `.expect("submit accepted")` at crates/event_store/src/writer/mod.rs:1328. It fires when `writer.submit(entry_draft(10))` returns `Err` immediately after spawn. In this test the backend is `DiskFailureBackend`, whose `append_batch` fails; submit should still return `Ok` because acceptance only requires enqueuing into the channel — a rejection means the channel is full, the writer thread already died and latched halt, or the run state prevents appends.
Source
Thrown at crates/event_store/src/writer/mod.rs:1328
captured_halt: (HaltCallback, Arc<Mutex<Vec<HaltReason>>>),
) {
// A writer-thread halt latches the shared flag; post-halt submits must
// reject rather than be accepted and silently dropped.
let (halt, captured) = captured_halt;
let config = WriterConfig {
max_batch_entries: 1,
..WriterConfig::default()
};
let writer = EventStoreWriter::spawn(
Box::new(DiskFailureBackend::default()),
get_atomic_clock_static(),
halt,
config,
)
.expect("spawn");
writer.submit(entry_draft(10)).expect("submit accepted");
let mut waited = Duration::ZERO;
while waited < Duration::from_secs(2) {
if !captured.lock().is_empty() {
break;
}
std::thread::sleep(Duration::from_millis(5));
waited += Duration::from_millis(5);
}
let reasons = captured.lock();
assert_eq!(reasons.len(), 1, "writer-thread halt did not fire");
assert!(
matches!(reasons.first(), Some(HaltReason::BackendDisk(_))),
"was {:?}",
reasons.first(),
);
drop(reasons);View on GitHub (pinned to 18893faf8b)
Solutions
- Submit promptly after `spawn` and ensure the halt threshold is generous relative to test timing so the first submit is accepted before any halt can latch.
- Match on the `SubmitError` (`Closed` vs `HaltSignaled`) instead of expect to identify whether the writer thread died before the submit.
- Verify `open_run(manifest(...))` was called on the backend the writer was spawned with.
- Increase `channel_capacity` so the first submit cannot be rejected for a full buffer.
Example fix
// before
writer.submit(entry_draft(10)).expect("submit accepted");
// after
writer
.submit(entry_draft(10))
.expect("first submit must be accepted before any halt can latch"); Defensive patterns
Strategy: retry
Validate before calling
// Ensure no halt has latched before submitting assert!(captured.lock().is_empty(), "halt already fired; submits will be refused");
Type guard
match writer.submit(entry_draft(10)) {
Ok(_) => {},
Err(SubmitError::Closed) => eprintln!("writer halted; not accepting"),
Err(e) => eprintln!("submit rejected: {e:?}"),
} Try / catch
writer.submit(entry_draft(10))
.unwrap_or_else(|e| panic!("first submit rejected: {e:?}")); Prevention
- Submit immediately after spawn, before halt timers can fire.
- Open the run on the backend before spawning the writer.
- Size channel_capacity >= 1 for the first submit.
- On CI, widen halt_threshold to absorb scheduling delays.
When it happens
Trigger: Submitting to a writer whose channel is saturated, whose writer thread has already halted (latched flag makes later submits return `SubmitError::Closed`), or whose run was never opened / already sealed on the backend.
Common situations: Backpressure stalls with tiny `channel_capacity` + long backend operations; running tests on slow CI where the disk-failure halt fires before the submit lands; forgetting to call `open_run` on the shared backend.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- first submit fits
- second submit must be buffered by the clamped capacity
- second submit fills the slot
- in-flight mutex poisoned
- wallet balance mutex poisoned
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5b2e72fd6273b3e4.
Report an issue: GitHub.