{"record":{"id":"1a24dee7476b4338","repo":"nautechsystems/nautilus_trader","slug":"first-submit-fits-in-channel-before-writer-fail-st","errorCode":null,"errorMessage":"first submit fits in channel before writer fail-stops","messagePattern":"first submit fits in channel before writer fail-stops","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/event_store/src/writer/mod.rs","lineNumber":1626,"sourceCode":"        let (halt, captured) = captured_halt;\n        let backend = DiskFailureBackend::default();\n\n        let writer = EventStoreWriter::spawn(\n            Box::new(backend),\n            get_atomic_clock_static(),\n            halt,\n            WriterConfig {\n                channel_capacity: 4,\n                max_batch_entries: 1,\n                max_batch_latency: Duration::from_millis(1),\n                halt_threshold: Duration::from_millis(500),\n            },\n        )\n        .expect(\"spawn\");\n\n        writer\n            .submit(entry_draft(10))\n            .expect(\"first submit fits in channel before writer fail-stops\");\n\n        // Wait until the writer fail-stops and the halt fires.\n        let mut waited = Duration::ZERO;\n        let deadline = Duration::from_millis(500);\n        while captured.lock().is_empty() && waited < deadline {\n            std::thread::sleep(Duration::from_millis(10));\n            waited += Duration::from_millis(10);\n        }\n\n        let captured_reasons = captured.lock();\n        assert!(matches!(\n            captured_reasons.first(),\n            Some(HaltReason::BackendDisk(_))\n        ));\n        drop(captured_reasons);\n\n        // Subsequent submits return Closed once the writer thread has exited.\n        let mut closed_seen = false;","sourceCodeStart":1608,"sourceCodeEnd":1644,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/event_store/src/writer/mod.rs#L1608-L1644","documentation":"Panic from `.expect(\"first submit fits in channel before writer fail-stops\")` in `backend_disk_error_fires_halt_and_closes_writer`. The submit must be accepted into the channel (capacity 4) before the asynchronous disk failure fail-stops the writer; a rejected submit panics.","triggerScenarios":"`writer.submit(entry_draft(10))` returns `Err` before the backend's disk error is processed — the writer already halted/closed at startup, the channel is wrongly reported full, or the DiskFailureBackend triggers failure during submit rather than during append.","commonSituations":"A fail-stop path that closes the writer before the first queued entry lands, halt state set eagerly at spawn, or channel accounting marking capacity unavailable on an empty channel.","solutions":["Log the `SubmitError` variant to see whether it is Closed, HaltSignaled, or Full.","Ensure the writer accepts submissions until the backend append actually fails.","Verify the halt callback has not fired before the submit (the test waits for it afterwards).","Fix submit/closed-state ordering so fail-stop happens after queued entries are accepted."],"exampleFix":"// before\nwriter.submit(entry_draft(10)).expect(\"first submit fits in channel before writer fail-stops\");\n// after\nwriter.submit(entry_draft(10))\n    .unwrap_or_else(|e| panic!(\"submit before fail-stop rejected: {e:?}\"));","handlingStrategy":"try-catch","validationCode":"// confirm writer not halted/closed before submit\nassert!(!writer.is_closed());","typeGuard":null,"tryCatchPattern":"writer.submit(d).unwrap_or_else(|e| panic!(\"submit rejected: {e:?}\"));","preventionTips":["Fail-stop only after the backend append fails, not at submit time","Accept queued entries until the failure is processed","Track writer state transitions explicitly"],"tags":["rust","panic","submit-error","fail-stop"],"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-14T00:17:10.932Z"}