nautechsystems/nautilus_trader · error

second submit must be buffered by the clamped capacity

Error message

second submit must be buffered by the clamped capacity

What it means

A test panic from `.expect("second submit must be buffered by the clamped capacity")` at crates/event_store/src/writer/mod.rs:1303. It fires when the deferred `submit(entry_draft(11))` result is `Err` — i.e. the writer rejected the submit instead of buffering it. The test asserts that when `channel_capacity: 0` is configured, the writer clamps it to a working capacity so the second submit is buffered rather than refused with `SubmitError::Closed` or `SubmitError::HaltSignaled`.

Source

Thrown at crates/event_store/src/writer/mod.rs:1303

            std::thread::sleep(Duration::from_millis(5));
            waited += Duration::from_millis(5);
        }
        assert_eq!(
            appends_seen.load(Ordering::SeqCst),
            1,
            "writer thread did not reach the gated append",
        );

        // Release the gate before asserting so a regression fails instead of
        // hanging the writer join.
        let second_submit = writer.submit(entry_draft(11));

        let (lock, cvar) = &*gate;
        *lock.lock() = true;
        cvar.notify_all();

        let final_hwm = writer.close(run_ended_draft()).expect("close");
        second_submit.expect("second submit must be buffered by the clamped capacity");
        assert_eq!(final_hwm, 3);
        assert!(captured.lock().is_empty());
    }

    #[rstest]
    fn submit_after_writer_thread_halt_returns_closed(
        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()),

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Fix the capacity clamp so `channel_capacity == 0` is clamped to at least 1 before the channel is created in `EventStoreWriter::spawn`.
  2. Check the concrete `SubmitError` (replace expect with `unwrap_err`/`matches!`) to distinguish `Closed` (halt latched) from `HaltSignaled` (stall threshold too low).
  3. Increase `halt_threshold` in the test config if the submit legitimately stalls because the gated backend holds `append_batch` too long.
  4. Ensure the gate is released (`lock = true; cvar.notify_all()`) before the retry loop exhausts, so the buffered submit can be accepted.

Example fix

// before
second_submit.expect("second submit must be buffered by the clamped capacity");
// after
second_submit
    .expect("clamped capacity must buffer the second submit instead of rejecting it");
Defensive patterns

Strategy: validation

Validate before calling

// Validate config before spawn
assert!(config.halt_threshold >= Duration::from_millis(100),
    "halt_threshold too small for gated-backend tests");

Type guard

match second_submit {
    Ok(()) => {},
    Err(SubmitError::Closed) => eprintln!("halt latched; submit refused"),
    Err(SubmitError::HaltSignaled { .. }) => eprintln!("stall threshold tripped"),
}

Try / catch

second_submit.unwrap_or_else(|e| panic!("second submit rejected: {e:?}"));

Prevention

When it happens

Trigger: Configuring `WriterConfig { channel_capacity: 0, .. }` while the writer thread is blocked inside a gated `append_batch`, then calling `writer.submit(...)`; if the capacity clamp regresses (submit rejected outright instead of buffered), the expect panics.

Common situations: Zero-capacity or under-provisioned channel configurations; CI runs of the `zero_channel_capacity_is_clamped_and_submit_buffers` rstest after a refactor of the submit retry loop or channel sizing.

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


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/db83bef8f63cc51b. Report an issue: GitHub.