nautechsystems/nautilus_trader · error · anyhow::Error
Execution payload batch size must be positive
Error message
Execution payload batch size must be positive
What it means
migrate_execution_payload_batch validates its batch_size parameter before opening a transaction. Migration proceeds in bounded batches, so a non-positive batch size is a caller programming error rejected up front with anyhow::ensure!.
Source
Thrown at crates/adapters/blockchain/src/cache/database.rs:4895
ON CONFLICT (key_id) DO NOTHING",
)
.bind(keys.active_key_id().as_slice())
.execute(&mut *transaction)
.await
.context("failed to initialize execution payload key state")?;
transaction
.commit()
.await
.context("failed to commit execution payload activation")?;
Ok(())
}
async fn migrate_execution_payload_batch(
&self,
keys: &PayloadKeySet,
batch_size: i64,
) -> anyhow::Result<bool> {
anyhow::ensure!(
batch_size > 0,
"Execution payload batch size must be positive"
);
let mut transaction = self
.pool
.begin()
.await
.context("failed to start execution payload migration batch")?;
lock_execution_payload_operation(&mut transaction).await?;
let state_row = sqlx::query(
"SELECT deployment_id, protocol_version, operation, active_key_id \
FROM execution_payload_state WHERE component = 'signed_transactions' FOR UPDATE",
)
.fetch_optional(&mut *transaction)
.await
.context("failed to lock execution payload migration state")?
.ok_or_else(|| anyhow::anyhow!("Execution payload migration state is missing"))?;
let state = execution_payload_state_from_row(&state_row)?;View on GitHub (pinned to 18893faf8b)
Solutions
- Pass a positive batch size (>= 1); clamp or validate the value at the call site
- Fix the config/source supplying batch_size so it cannot be zero or negative
- Use .max(1) or a checked computation when deriving batch_size from counters
Example fix
// before let migrated = db.migrate_execution_payload_batch(&keys, batch_size).await?; // after let batch_size = batch_size.max(1); let migrated = db.migrate_execution_payload_batch(&keys, batch_size).await?;
Defensive patterns
Strategy: validation
Validate before calling
fn validate_batch_size(batch_size: i64) -> Result<i64, String> {
if batch_size > 0 { Ok(batch_size) } else { Err(format!("batch_size must be positive, got {batch_size}")) }
} Type guard
fn is_positive_batch(n: i64) -> bool { n > 0 } Try / catch
let batch_size = validate_batch_size(cfg.migrate_batch_size).map_err(anyhow::Error::msg)?; let done = db.migrate_execution_payload_batch(&keys, batch_size).await?;
Prevention
- Validate config-driven batch sizes at load time
- Use non-zero defaults and reject zero/negative config values eagerly
- When deriving batch size from counters, clamp with .max(1)
When it happens
Trigger: Calling migrate_execution_payload_batch with batch_size <= 0 (e.g. 0, or a negative value from a misparsed config or an integer underflow when computing remaining work).
Common situations: Config file with migrate_batch_size: 0; computing batch_size as remaining - processed when remaining <= processed; wiring a signed value from the wrong source.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- run_config_id is required when a BacktestNode is provided
- {e}
- instrument_ids, client_order_ids, and venue_order_ids must h
- `price_precisions` length ({}) must match `instrument_ids` l
- start must not be later than end
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/c80b378ce178f1c7.
Report an issue: GitHub.