nautechsystems/nautilus_trader · error
Stream message missing payload: {stream_msg:?}
Error message
Stream message missing payload: {stream_msg:?} What it means
A Redis stream entry decoded by decode_bus_message must include a 'payload' header with the message body. When the entry parsed successfully but no 'payload' pair was present, the decoder bails because a BusMessage without a body is meaningless. It signals an entry that does not conform to the message-bus wire format.
Source
Thrown at crates/infrastructure/src/redis/msgbus.rs:882
encoding = value
.parse()
.map_err(|e| anyhow::anyhow!("Error parsing encoding: {e}"))?;
}
b"payload" => {
let redis::Value::BulkString(bytes) = &pair[1] else {
anyhow::bail!("Invalid payload format: {stream_msg:?}");
};
payload = Some(Bytes::copy_from_slice(bytes));
}
_ => {}
}
}
let Some(topic) = topic else {
anyhow::bail!("Stream message missing topic: {stream_msg:?}");
};
let Some(payload) = payload else {
anyhow::bail!("Stream message missing payload: {stream_msg:?}");
};
let payload_type = match type_name {
Some(type_name) if typed_payload => BusPayloadType::from_typed_name(&type_name)
.ok_or_else(|| anyhow::anyhow!("Unknown typed payload '{type_name}'"))?,
Some(type_name) => BusPayloadType::from_name(&type_name),
None if typed_payload => {
anyhow::bail!("Typed stream message missing type: {stream_msg:?}")
}
None => BusPayloadType::Custom(Ustr::default()),
};
Ok(BusMessage::with_str_topic(
topic,
payload_type,
payload,
encoding,
))
}View on GitHub (pinned to 18893faf8b)
Solutions
- Inspect the entry (XRANGE) and verify whether it legitimately lacks a payload; if it is a control entry, exclude that stream from the bus consumer.
- Fix the producer so every published message includes a 'payload' BulkString.
- Skip or XDEL the payload-less entry so the consumer can continue.
- Verify the stream key/topic the consumer is reading matches what the producer publishes.
Example fix
// before (producer bug omits payload) XADD mystream * topic "quotes.X" encoding "json" // after XADD mystream * topic "quotes.X" payload "<body>" encoding "json"
Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure payload present before publishing
fn entry_has_payload(fields: &[(&str, &[u8])]) -> bool {
fields.iter().any(|(k, _)| *k == "payload")
} Type guard
fn payload_of(fields: &[(String, redis::Value)]) -> Option<&Vec<u8>> {
fields.iter().find(|(k, _)| k == "payload")
.and_then(|(_, v)| match v { redis::Value::BulkString(b) => Some(b), _ => None })
} Try / catch
match stream_messages(&mut con, stream, count).await {
Ok(msgs) => { /* use msgs */ }
Err(e) if e.to_string().contains("missing payload") => {
tracing::warn!("skipping payload-less entry: {e}");
}
Err(e) => return Err(e),
} Prevention
- Always set a 'payload' BulkString when publishing to the bus.
- Route heartbeat/control entries to separate streams, not the bus stream.
- Test producers end-to-end before pointing consumers at the stream.
- Verify the consumer reads the same stream key the producer writes.
When it happens
Trigger: stream_messages encounters an entry with headers such as topic/type/encoding but no 'payload' field — e.g. a heartbeat or control entry written by a different component, a producer bug that drops the payload, or a foreign entry in the stream.
Common situations: Stream key shared with control/heartbeat entries from other tooling; producer version skew; manual redis-cli XADD during testing; consumer attached to the wrong stream.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
- Stream message missing topic: {stream_msg:?}
- Invalid payload format: {stream_msg:?}
- Typed stream message missing type: {stream_msg:?}
- Unknown payload kind '{value}'
- Stream receiver already taken
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/d81d592d2966172b.
Report an issue: GitHub.