nautechsystems/nautilus_trader · error · anyhow::Error
invalid type for 'bbo_side_type': {value}, expected string
Error message
invalid type for 'bbo_side_type': {value}, expected string What it means
parse_bybit_tp_sl_params requires 'bbo_side_type' to be a string because it is subsequently parsed into the BybitBboSideType enum. If the value exists but is not a string, the parser bails early rather than attempting coercions.
Source
Thrown at crates/adapters/bybit/src/common/parse.rs:1933
})?;
result.position_idx = Some(match idx {
0 => BybitPositionIdx::OneWay,
1 => BybitPositionIdx::BuyHedge,
2 => BybitPositionIdx::SellHedge,
_ => anyhow::bail!("invalid 'position_idx': {idx}, expected 0, 1, or 2"),
});
}
let has_bbo_side_type = params.get("bbo_side_type").is_some();
let has_bbo_level = params.get("bbo_level").is_some();
if has_bbo_side_type != has_bbo_level {
anyhow::bail!("'bbo_side_type' and 'bbo_level' must be provided together");
}
if let Some(value) = params.get("bbo_side_type") {
let side_type = value.as_str().ok_or_else(|| {
anyhow::anyhow!("invalid type for 'bbo_side_type': {value}, expected string")
})?;
result.bbo_side_type = Some(parse_bbo_side_type(side_type)?);
}
if let Some(value) = params.get("bbo_level") {
let level = if let Some(s) = value.as_str() {
s.to_string()
} else if let Some(i) = value.as_i64() {
i.to_string()
} else if let Some(u) = value.as_u64() {
u.to_string()
} else {
anyhow::bail!("invalid type for 'bbo_level': {value}, expected string or integer");
};
result.bbo_level = Some(parse_bbo_level(level)?);
}
Ok(result)View on GitHub (pinned to 18893faf8b)
Solutions
- Pass bbo_side_type as a string (the expected enum representation)
- Coerce the config value with .to_string()/as_str before inserting it
- Also ensure bbo_level is supplied together with bbo_side_type, or you hit the pairing error next
Example fix
// before
let params = serde_json::json!({"bbo_side_type": 2, "bbo_level": 1});
// after
let params = serde_json::json!({"bbo_side_type": "Spot", "bbo_level": 1}); Defensive patterns
Strategy: validation
Validate before calling
if let Some(v) = params.get("bbo_side_type") {
anyhow::ensure!(v.is_string(), "bbo_side_type must be a string");
anyhow::ensure!(params.contains_key("bbo_level"), "bbo_level required with bbo_side_type");
} Type guard
fn is_valid_bbo_side_type(v: &serde_json::Value) -> bool {
v.as_str().is_some()
} Try / catch
match parse_bybit_tp_sl_params(¶ms) {
Ok(p) => p,
Err(e) if e.to_string().contains("bbo") => {
eprintln!("invalid BBO params: {e}");
return Err(e);
}
Err(e) => return Err(e),
} Prevention
- Always pair bbo_side_type with bbo_level
- Serialize enum variants with their string representation (serde) before inserting into params
- Unit-test params builders with representative payloads
When it happens
Trigger: Passing params["bbo_side_type"] as a non-string value (number, bool, object) in the Bybit TP/SL params map.
Common situations: Programmatic params construction or config deserialization where bbo_side_type lost its string type; also forgetting that bbo_side_type must be paired with bbo_level.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- invalid type for 'smp_type': {value}, expected string
- invalid type for 'position_idx': {value}, expected integer
- invalid type for 'order_iv': {value}, expected string or num
- invalid type for 'mmp': {value}, expected bool
- invalid type for 'bbo_level': {value}, expected string or in
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/5fc7de570a3bf7f2.
Report an issue: GitHub.