nautechsystems/nautilus_trader · error
Payload operation batch size must be between 1 and {MAX_PAYL
Error message
Payload operation batch size must be between 1 and {MAX_PAYLOAD_OPERATION_BATCH_SIZE} What it means
`validate_payload_operation_batch_size` enforces that the caller-supplied payload operation batch size is within [1, MAX_PAYLOAD_OPERATION_BATCH_SIZE] before converting it to i64. Values of 0 or above the maximum are rejected since the batch protocol requires a bounded, positive batch size.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:3590
fn replacement_scan_range(from_block: u64, head_block: u64) -> anyhow::Result<RangeInclusive<u64>> {
anyhow::ensure!(
head_block >= from_block,
"Canonical head {head_block} is behind execution creation block {from_block}"
);
let max_end = from_block.saturating_add(MAX_REPLACEMENT_SCAN_BLOCKS - 1);
Ok(from_block..=head_block.min(max_end))
}
fn current_unix_secs() -> anyhow::Result<u64> {
SystemTime::now()
.duration_since(UNIX_EPOCH)
.map_err(|_| anyhow::anyhow!("Trusted host clock precedes the Unix epoch"))
.map(|duration| duration.as_secs())
}
fn validate_payload_operation_batch_size(batch_size: usize) -> anyhow::Result<i64> {
anyhow::ensure!(
(1..=MAX_PAYLOAD_OPERATION_BATCH_SIZE).contains(&batch_size),
"Payload operation batch size must be between 1 and {MAX_PAYLOAD_OPERATION_BATCH_SIZE}"
);
Ok(i64::try_from(batch_size).expect("bounded payload batch size fits i64"))
}
fn current_execution_hash(
intent_id: i64,
hashes: &[ExecutionTransactionHashRow],
) -> anyhow::Result<&ExecutionTransactionHashRow> {
let mut current = hashes.iter().filter(|row| row.current);
let row = current
.next()
.ok_or_else(|| anyhow::anyhow!("Execution intent {intent_id} has no current hash"))?;
anyhow::ensure!(
current.next().is_none(),
"Execution intent {intent_id} has more than one current hash"
);View on GitHub (pinned to 18893faf8b)
Solutions
- Set the batch size to a value between 1 and MAX_PAYLOAD_OPERATION_BATCH_SIZE (check the constant for the current limit).
- Clamp or validate the configured value at config-load time.
- If a larger batch is genuinely needed, raise the constant in code rather than passing an out-of-range runtime value.
Example fix
// before payload_batch_size = 0 // after payload_batch_size = 50 // 1 <= n <= MAX_PAYLOAD_OPERATION_BATCH_SIZE
Defensive patterns
Strategy: validation
Validate before calling
const MAX: usize = MAX_PAYLOAD_OPERATION_BATCH_SIZE as usize;
anyhow::ensure!((1..=MAX).contains(&batch_size), "batch_size {batch_size} outside 1..={MAX}"); Try / catch
match validate_payload_operation_batch_size(cfg.batch_size) {
Err(_) => use_default_batch_size(),
Ok(size) => submit_with_batch_size(size),
} Prevention
- Validate batch size at config-load time, not at call time
- Never use 0 to mean 'unlimited'; use the documented default
- Clamp parsed values into [1, MAX_PAYLOAD_OPERATION_BATCH_SIZE]
When it happens
Trigger: Configuring or calling payload operation submission with `batch_size = 0` or `batch_size > MAX_PAYLOAD_OPERATION_BATCH_SIZE` — e.g. a config file with `payload_batch_size: 0`, or a user trying to 'send everything at once' with an oversized value.
Common situations: Zero interpreted as 'unlimited' by users; copy-pasting a batch size from another adapter with a different maximum; environment variable parsed into 0 on malformed input.
Understand the failure class
Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.
Related errors
- request_rate_per_second must be greater than zero
- order_request_rate_per_second must be greater than zero
- heartbeat_secs must be positive when set
- heartbeat_timeout_secs must cover at least two server heartb
- `router_addresses` must contain at least one router address
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/3ef68193209781e8.
Report an issue: GitHub.