nautechsystems/nautilus_trader · error
second submit fits
Error message
second submit fits
What it means
Panic from `.expect("second submit fits")` in `record_snapshot_anchor_signals_halt_when_submit_stalls`. After the first entry is confirmed blocked inside the backend append, a second submit must still be accepted into the single-slot channel; an `Err` panics.
Source
Thrown at crates/event_store/src/writer/mod.rs:1565
max_batch_entries: 1,
max_batch_latency: Duration::from_secs(30),
halt_threshold,
},
)
.expect("spawn");
writer.submit(entry_draft(10)).expect("first submit fits");
let mut waited = Duration::ZERO;
while appends_seen.load(Ordering::SeqCst) == 0 && waited < Duration::from_secs(1) {
std::thread::sleep(Duration::from_millis(2));
waited += Duration::from_millis(2);
}
assert_eq!(
appends_seen.load(Ordering::SeqCst),
1,
"writer must be blocked inside the first backend append",
);
writer.submit(entry_draft(11)).expect("second submit fits");
let err = writer
.record_snapshot_anchor("cache://position-snapshots/P-1/0", "blake3:abc")
.expect_err("snapshot anchor submit must time out");
let post_halt = writer
.submit(entry_draft(12))
.expect_err("post-halt submit");
let (lock, cvar) = &*gate;
*lock.lock() = true;
cvar.notify_all();
match err {
EventStoreError::Backend(msg) => {
assert!(
msg.contains("snapshot anchor submit stalled"),
"msg was: {msg}"
);View on GitHub (pinned to 18893faf8b)
Solutions
- Print the `SubmitError` variant to identify Full/Closed/HaltSignaled.
- Confirm the first entry truly left the channel (the test asserts `appends_seen == 1` just before).
- Check halt logic has not fired — the gate is still closed and threshold is 50ms.
- Fix channel slot accounting so an in-backend (dequeue) entry frees its channel slot.
Example fix
// before
writer.submit(entry_draft(11)).expect("second submit fits");
// after
writer.submit(entry_draft(11)).unwrap_or_else(|e| panic!("second submit rejected: {e:?}")); Defensive patterns
Strategy: try-catch
Validate before calling
// wait until the in-flight entry left the channel before submitting again
while writer.pending() >= capacity { sleep(1ms); } Try / catch
writer.submit(d).unwrap_or_else(|e| panic!("second submit rejected: {e:?}")); Prevention
- Fix capacity accounting to free slots once dequeued
- Verify halt has not fired before subsequent submits
- Log SubmitError variants to distinguish Full/Closed/HaltSignaled
When it happens
Trigger: `writer.submit(entry_draft(11))` returns `Err` when the channel slot should be free (the first entry left the channel and is blocked in append) — capacity accounting bug, premature halt/closed state, or the writer failing fast on backpressure.
Common situations: Channel capacity counted as occupied while an entry is being processed in the backend, halt logic firing before `halt_threshold` (50ms) elapses, or `SubmitError::Closed` surfacing because the writer thread errored.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- second submit must be buffered by the clamped capacity
- first submit fits in channel before writer fail-stops
- in-flight mutex poisoned
- wallet balance mutex poisoned
- instrument update lock poisoned
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/931cf5cdf8b80a3b.
Report an issue: GitHub.