nautechsystems/nautilus_trader · error
`price_precisions` length ({}) must match `instrument_ids` l
Error message
`price_precisions` length ({}) must match `instrument_ids` length ({}) What it means
The live Databento client's `subscribe` accepts an optional `price_precisions` list that must be parallel to `instrument_ids` (one precision per instrument, entries may be None). When the list is provided but its length differs from the instrument list, the client bails before subscribing.
Source
Thrown at crates/adapters/databento/src/live.rs:191
///
/// # Errors
///
/// Returns an error if symbology, schema, timestamp, or precision inputs are invalid,
/// or if the command cannot be sent to the feed handler.
#[expect(clippy::needless_pass_by_value)]
pub fn subscribe(
&mut self,
schema: String,
instrument_ids: Vec<InstrumentId>,
start: Option<u64>,
snapshot: Option<bool>,
price_precisions: Option<Vec<Option<u8>>>,
stype_in: Option<String>,
) -> anyhow::Result<()> {
if let Some(precisions) = &price_precisions
&& precisions.len() != instrument_ids.len()
{
anyhow::bail!(
"`price_precisions` length ({}) must match `instrument_ids` length ({})",
precisions.len(),
instrument_ids.len()
);
}
let symbols: Vec<String> = instrument_ids
.iter()
.map(|id| id.symbol.to_string())
.collect();
let first_symbol = symbols
.first()
.ok_or_else(|| anyhow::anyhow!("No symbols provided"))?;
let stype_in = match stype_in {
Some(stype_in) => dbn::SType::from_str(&stype_in)?,
None => infer_symbology_type(first_symbol),
};
let symbols: Vec<&str> = symbols.iter().map(String::as_str).collect();View on GitHub (pinned to 18893faf8b)
Solutions
- Make `price_precisions` exactly the same length as `instrument_ids`, using None entries for defaults.
- Pass `price_precisions=None` if you don't need per-instrument precisions.
- In Python, zip or derive precisions from the same source as the instrument IDs.
- Assert lengths match before calling subscribe.
Example fix
// before precisions = [8, 4] # 2 entries await client.subscribe(instrument_ids, price_precisions=precisions) # 3 instruments // after precisions = [8, None, 4] # one entry (or None) per instrument await client.subscribe(instrument_ids, price_precisions=precisions)
Defensive patterns
Strategy: validation
Validate before calling
if price_precisions is not None:
assert len(price_precisions) == len(instrument_ids), (
f"price_precisions ({len(price_precisions)}) must match instrument_ids ({len(instrument_ids)})") Prevention
- Build precisions from the same collection as instrument IDs (zip/derive, not parallel literals)
- Prefer price_precisions=None and let the client infer precisions
- Filter instruments and precisions together in one operation
When it happens
Trigger: Calling `subscribe` (directly or via `py_subscribe`) with `instrument_ids` of length N and `price_precisions` = Some(vec) of length != N, including passing an empty precision list with non-empty instruments.
Common situations: Building the precision list in Python from a different collection than the instrument IDs; filtering instruments but forgetting to filter precisions; passing price_precisions=[] thinking it means 'use defaults'.
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
- No feed handler found for dataset: {dataset}
- No symbols provided
- WS user data subscription timed out
- run_config_id is required when a BacktestNode is provided
- {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/6f268f6270b7d9dc.
Report an issue: GitHub.