nautechsystems/nautilus_trader · error
Invalid hash index payload for '{index_key}': expected field
Error message
Invalid hash index payload for '{index_key}': expected field-value pairs What it means
insert_index in the Redis cache adapter validates that the payload for INDEX_ORDER_CLIENT (an HSET index) contains an even number of byte slices so they can be paired as hash field-value entries. When the value slice length is not a multiple of 2, it cannot form field-value pairs, so the insert is rejected with this error before any Redis command is issued. It prevents silently writing a truncated or mispaired hash.
Source
Thrown at crates/infrastructure/src/redis/cache.rs:982
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 => {
insert_set(pipe, key, value[0].as_ref());
Ok(())
}
INDEX_ORDER_POSITION => {
insert_hset(pipe, key, value[0].as_ref(), value[1].as_ref());
Ok(())
}
INDEX_ORDER_CLIENT => {
if !value.len().is_multiple_of(2) {
anyhow::bail!(
"Invalid hash index payload for '{index_key}': expected field-value pairs"
);
}
let entries = value
.as_chunks::<2>()
.0
.iter()
.map(|entry| (entry[0].as_ref(), entry[1].as_ref()))
.collect::<Vec<(&[u8], &[u8])>>();
pipe.hset_multiple(key, &entries);
Ok(())
}
_ => anyhow::bail!("Index unknown '{index_key}' on insert"),
}
}
fn insert_string(pipe: &mut Pipeline, key: &str, value: &[u8]) {View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the caller's `value` construction for the order-client index and ensure every field is immediately followed by its value (even element count).
- Log/print value.len() and each element at the call site to find the unpaired element.
- If a field is optional, pass both field and value (e.g. empty value) rather than omitting one half of the pair.
- Add a unit test asserting the payload length is a multiple of 2 before calling insert.
Example fix
// before let value = vec![client_order_id_bytes]; // odd: field without value insert_index(pipe, key, value, INDEX_ORDER_CLIENT)?; // after let value = vec![client_order_id_bytes, order_id_bytes]; // field-value pair insert_index(pipe, key, value, INDEX_ORDER_CLIENT)?;
Defensive patterns
Strategy: validation
Validate before calling
// Rust
if value.len() % 2 != 0 {
return Err(anyhow::anyhow!(
"order-client index payload must contain field-value pairs; got {} elements",
value.len()
));
} Try / catch
// Python bindings
try:
cache.insert(index_key, key, payload)
except RuntimeError as e:
if "expected field-value pairs" in str(e):
log.error("Mispaired index payload: %s", payload)
else:
raise Prevention
- Always build index payloads as explicit (field, value) tuples before flattening.
- Assert payload length is even in unit tests for index writes.
- Never append index fields conditionally without their values; use empty values for optional fields.
When it happens
Trigger: Calling cache.insert with an index key of INDEX_ORDER_CLIENT where the `value: &[Bytes]` argument has an odd number of elements (e.g. only the client_order_id field without its value, or an extra stray element).
Common situations: Serialization/persistence code that appends index fields one at a time but drops the last value; a caller updated to add a new field pair but only partially writing it; hand-built payloads in custom adapters or test harnesses misaligning field/value ordering.
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 send to channel: {e}
- Unsupported operation: `insert` for collection '{collection}
- Index unknown '{index_key}' on insert
- Unsupported operation: `replace_list` for collection '{colle
- Unsupported operation: `update` for collection '{collection}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/29422c89c7360e30.
Report an issue: GitHub.