nautechsystems/nautilus_trader · error
Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was
Error message
Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was {key} What it means
get_collection_key splits a Redis key on the REDIS_DELIMITER (':') and returns the collection prefix (e.g. 'orders', 'positions'). If the key contains no delimiter it cannot be classified, so this error is thrown. It guards against malformed keys reaching the index/read layer.
Source
Thrown at crates/infrastructure/src/redis/queries.rs:969
let mut position = Position::new(&instrument, first_fill.clone());
for fill in remaining_fills {
if position.trade_ids().contains(&fill.trade_id) {
anyhow::bail!(
"Duplicate fill event for position {position_id}: {}",
fill.trade_id
);
}
position.apply(fill);
}
Ok(Some(position))
}
fn get_collection_key(key: &str) -> anyhow::Result<&str> {
key.split_once(REDIS_DELIMITER)
.map(|(collection, _)| collection)
.ok_or_else(|| {
anyhow::anyhow!("Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was {key}")
})
}
async fn read_index(conn: &mut ConnectionManager, key: &str) -> anyhow::Result<Vec<Bytes>> {
let index_key = get_index_key(key)?;
match index_key {
INDEX_ORDER_IDS
| INDEX_ORDERS
| INDEX_ORDERS_OPEN
| INDEX_ORDERS_CLOSED
| INDEX_ORDERS_EMULATED
| INDEX_ORDERS_INFLIGHT
| INDEX_POSITIONS
| INDEX_POSITIONS_OPEN
| INDEX_POSITIONS_CLOSED => Self::read_set(conn, key).await,
INDEX_ORDER_POSITION | INDEX_ORDER_CLIENT => Self::read_hset(conn, key).await,
_ => anyhow::bail!("Index unknown '{index_key}' on read"),
}View on GitHub (pinned to 18893faf8b)
Solutions
- Construct keys with the full form '<collection>:<rest>' using the library's key helpers (e.g. get_index_key / documented key formats).
- Check the offending key for a missing or mistyped delimiter (e.g. using '-' instead of ':').
- Pass the complete Redis key, not just the collection or suffix portion.
- If migrating from external storage, normalize keys to the colon-delimited scheme before loading.
Example fix
// before
let collection = get_collection_key("positions.OTP-001")?; // no ':' delimiter
// after
let collection = get_collection_key("positions:OTP-001")?; Defensive patterns
Strategy: validation
Validate before calling
// Rust: ensure key is colon-delimited before use
fn is_valid_redis_key(key: &str) -> bool {
key.contains(':') && !key.starts_with(':') && !key.ends_with(':')
} Try / catch
if !is_valid_redis_key(key) {
return Err(anyhow::anyhow!("refusing to load malformed key: {key}"));
}
let collection = get_collection_key(key)?; Prevention
- Always compose Redis keys with the library's key builders instead of string concatenation.
- Remember the delimiter is ':'; never substitute '-' or '.' in custom tooling.
- Unit-test custom key construction against get_collection_key before deploying.
When it happens
Trigger: Calling internal read/index helpers (read_index, and any loader path that classifies keys) with a key string lacking ':', e.g. passing a bare name like "mykey" instead of "orders:mykey", or passing an index/data key with the prefix stripped incorrectly.
Common situations: Custom tooling composing Redis keys manually and omitting the delimiter; calling semi-internal APIs with raw collection names; keys constructed with a different delimiter convention in external code.
Understand the failure class
Background: "Invalid ... format", "must be in format X", "does not look like a ..." — invalid argument format errors across CLI tools and libraries — this error's family across 17 libraries.
Related errors
- Failed to parse instrument ID from key '{key}': {e}
- Invalid `key`, missing a '{REDIS_DELIMITER}' delimiter, was
- Invalid instrument key '{key}'
- Invalid `external_order_claims` instrument ID {claim}: {e}
- Invalid scientific notation exponent '{exponent}': must be a
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/7f36caa048327105.
Report an issue: GitHub.