nautechsystems/nautilus_trader · error · anyhow::Error
Blockchain execution transaction limits are required: allowe
Error message
Blockchain execution transaction limits are required: allowed_token_pairs, slippage_bps, max_slippage_bps, max_order_amount, deadline_seconds, max_quote_age_blocks, receipt_timeout_secs
What it means
The blockchain execution client refuses to sign or broadcast anything without hard transaction limits. Its constructor destructures seven Option fields of `BlockchainExecutionClientConfig` — allowed_token_pairs, slippage_bps, max_slippage_bps, max_order_amount, deadline_seconds, max_quote_age_blocks, receipt_timeout_secs — and bails if any is None. Because the fields are Option, a config that omits them still type-checks and only fails at client construction.
Source
Thrown at crates/adapters/blockchain/src/execution/client.rs:307
let (
Some(allowed_token_pairs),
Some(slippage_bps),
Some(max_slippage_bps),
Some(max_order_amount),
Some(deadline_seconds),
Some(max_quote_age_blocks),
Some(receipt_timeout_secs),
) = (
&config.allowed_token_pairs,
config.slippage_bps,
config.max_slippage_bps,
config.max_order_amount,
config.deadline_seconds,
config.max_quote_age_blocks,
config.receipt_timeout_secs,
)
else {
anyhow::bail!(
"Blockchain execution transaction limits are required: allowed_token_pairs, slippage_bps, max_slippage_bps, max_order_amount, deadline_seconds, max_quote_age_blocks, receipt_timeout_secs"
);
};
let mut parsed_pairs = HashSet::with_capacity(allowed_token_pairs.len());
for (token_in, token_out) in allowed_token_pairs {
parsed_pairs.insert((
validate_address(token_in.as_str())?,
validate_address(token_out.as_str())?,
));
}
if slippage_bps > max_slippage_bps {
anyhow::bail!(
"`slippage_bps` {slippage_bps} exceeds `max_slippage_bps` {max_slippage_bps}"
);
}
View on GitHub (pinned to 2114cf6f76)
Solutions
- Set all seven fields in BlockchainExecutionClientConfig: allowed_token_pairs, slippage_bps, max_slippage_bps, max_order_amount, deadline_seconds, max_quote_age_blocks, receipt_timeout_secs.
- Spell the keys exactly as listed in the error message — serde silently defaults unknown keys to None.
- Fail fast at config load: assert each of the seven Options is Some before constructing the client.
- Add a config lint or schema check so missing keys are reported by name at startup.
Example fix
// before: limits omitted -> client construction bails
let config = BlockchainExecutionClientConfig { /* ... */ ..defaults() };
let client = BlockchainExecutionClient::new(config, cache, clock).await?;
// after: all seven required limits provided
let config = BlockchainExecutionClientConfig {
allowed_token_pairs: Some(vec![(weth.clone(), usdc.clone())]),
slippage_bps: Some(50),
max_slippage_bps: Some(300),
max_order_amount: Some(10_000_000_000),
deadline_seconds: Some(120),
max_quote_age_blocks: Some(4),
receipt_timeout_secs: Some(90),
..config
}; Defensive patterns
Strategy: validation
Validate before calling
fn limits_complete(cfg: &BlockchainExecutionClientConfig) -> bool {
cfg.allowed_token_pairs.is_some()
&& cfg.slippage_bps.is_some()
&& cfg.max_slippage_bps.is_some()
&& cfg.max_order_amount.is_some()
&& cfg.deadline_seconds.is_some()
&& cfg.max_quote_age_blocks.is_some()
&& cfg.receipt_timeout_secs.is_some()
}
// assert at config load, before client construction Try / catch
Treat construction failure as fatal configuration error: log the seven field names from the message against the parsed config file and report which keys are absent/misspelled. Do not retry.
Prevention
- Spell the seven keys exactly as the error lists them.
- Fail fast on None at config load.
- Add a CI test that constructs the client from the shipped example config.
When it happens
Trigger: Building the client from a config where at least one of the seven fields is missing: a minimal example config, a JSON/TOML key typo (serde leaves the default None), or a test config with limits deliberately stripped.
Common situations: Copying a doc example that predates the required-limits change; typos like 'max_quote_age' vs 'max_quote_age_blocks'; environment-specific config files that drifted.
Understand the failure class
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
- `slippage_bps` {slippage_bps} exceeds `max_slippage_bps` {ma
- Finalized block {} does not contain transaction {}
- height must be positive, was {self.height}
- pandas is required for visualization; install it with `pip i
- Execution schema version {} is newer than supported version
AI-assisted analysis of nautechsystems/nautilus_trader@2114cf6f76 (2026-08-21).
Data as JSON: /api/errors/fb9b347b713ce329.
Report an issue: GitHub.