nautechsystems/nautilus_trader · error
Invalid depth {depth}, must be 0, 50, or 400
Error message
Invalid depth {depth}, must be 0, 50, or 400 What it means
OKX order-book depth subscriptions only accept 0 (full book), 50, or 400 levels. subscribe_book validates the requested depth before mapping it to a channel and bails with anyhow if the value is anything else. This prevents building a subscription OKX would reject.
Source
Thrown at crates/adapters/okx/src/websocket/client.rs:1430
/// - depth 50: Requires VIP4+, subscribes to `books50-l2-tbt`
/// - depth 0 or 400:
/// - VIP5+: subscribes to `books-l2-tbt` (400 depth, fastest)
/// - Below VIP5: subscribes to `books` (standard depth)
///
/// # Errors
///
/// Returns an error if:
/// - Subscription request fails
/// - depth is 50 but VIP level is below 4
pub async fn subscribe_book_with_depth(
&self,
instrument_id: InstrumentId,
depth: u16,
) -> anyhow::Result<()> {
let vip = self.vip_level();
if !matches!(depth, 0 | 50 | 400) {
anyhow::bail!("Invalid depth {depth}, must be 0, 50, or 400");
}
if depth == 50 && vip < OKXVipLevel::Vip4 {
anyhow::bail!("VIP level {vip} insufficient for 50 depth subscription (requires VIP4)");
}
let channel = select_book_channel(depth as usize, vip);
self.subscribe_inst_id(ws_channel_for_book(channel), instrument_id.symbol.inner())
.await?;
Ok(())
}
/// Subscribes to best bid/ask quote data for an instrument.
///
/// Provides tick-by-tick updates of the best bid and ask prices using the bbo-tbt channel.
/// Supports all instrument types: SPOT, MARGIN, SWAP, FUTURES, OPTION.
///
/// # ErrorsView on GitHub (pinned to 18893faf8b)
Solutions
- Change the requested depth to one of the allowed values: 0, 50, or 400
- If you need a smaller book, use depth 0 (full) and slice locally, or check the OKX docs for depth channel options
- Add config validation at startup so an invalid depth fails fast before connecting
Example fix
// before subscribe_book(inst, 10).await?; // after subscribe_book(inst, 50).await?; // or 0 / 400
Defensive patterns
Strategy: validation
Validate before calling
const VALID_DEPTHS: [u16; 3] = [0, 50, 400];
if !VALID_DEPTHS.contains(&depth) {
return Err(anyhow::anyhow!("depth {depth} not in [0, 50, 400]"));
} Prevention
- Constrain depth via an enum (Depth::Full | Depth::L50 | Depth::L400) instead of a raw u16
- Validate depth in config parsing at startup
When it happens
Trigger: Calling subscribe_book (or the subscribe-book data request path) with a depth other than 0, 50, or 400, e.g. depth=10 or depth=100 in the WebSocket client config or SubscriptionCommand.
Common situations: Hardcoding a depth that matches another exchange's tick sizes (Binance 5/10/20), typos in config, or porting code between adapters without adjusting depth values.
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
- `api_key`, `api_secret`, `api_passphrase` credentials must b
- Not a subscription channel: {kind}
- limit_price is required for batch order type {order_type:?}
- Invalid `BarSpecification` for channel, was {bar_spec}
- `tick_sz` is empty for {}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a5caed04d3b784ee.
Report an issue: GitHub.