{"record":{"id":"931cf5cdf8b80a3b","repo":"nautechsystems/nautilus_trader","slug":"second-submit-fits","errorCode":null,"errorMessage":"second submit fits","messagePattern":"second submit fits","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/event_store/src/writer/mod.rs","lineNumber":1565,"sourceCode":"                max_batch_entries: 1,\n                max_batch_latency: Duration::from_secs(30),\n                halt_threshold,\n            },\n        )\n        .expect(\"spawn\");\n\n        writer.submit(entry_draft(10)).expect(\"first submit fits\");\n        let mut waited = Duration::ZERO;\n        while appends_seen.load(Ordering::SeqCst) == 0 && waited < Duration::from_secs(1) {\n            std::thread::sleep(Duration::from_millis(2));\n            waited += Duration::from_millis(2);\n        }\n        assert_eq!(\n            appends_seen.load(Ordering::SeqCst),\n            1,\n            \"writer must be blocked inside the first backend append\",\n        );\n        writer.submit(entry_draft(11)).expect(\"second submit fits\");\n\n        let err = writer\n            .record_snapshot_anchor(\"cache://position-snapshots/P-1/0\", \"blake3:abc\")\n            .expect_err(\"snapshot anchor submit must time out\");\n        let post_halt = writer\n            .submit(entry_draft(12))\n            .expect_err(\"post-halt submit\");\n\n        let (lock, cvar) = &*gate;\n        *lock.lock() = true;\n        cvar.notify_all();\n\n        match err {\n            EventStoreError::Backend(msg) => {\n                assert!(\n                    msg.contains(\"snapshot anchor submit stalled\"),\n                    \"msg was: {msg}\"\n                );","sourceCodeStart":1547,"sourceCodeEnd":1583,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/event_store/src/writer/mod.rs#L1547-L1583","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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."],"exampleFix":"// before\nwriter.submit(entry_draft(11)).expect(\"second submit fits\");\n// after\nwriter.submit(entry_draft(11)).unwrap_or_else(|e| panic!(\"second submit rejected: {e:?}\"));","handlingStrategy":"try-catch","validationCode":"// wait until the in-flight entry left the channel before submitting again\nwhile writer.pending() >= capacity { sleep(1ms); }","typeGuard":null,"tryCatchPattern":"writer.submit(d).unwrap_or_else(|e| panic!(\"second submit rejected: {e:?}\"));","preventionTips":["Fix capacity accounting to free slots once dequeued","Verify halt has not fired before subsequent submits","Log SubmitError variants to distinguish Full/Closed/HaltSignaled"],"tags":["rust","panic","submit-error","channel-capacity"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}