nautechsystems/nautilus_trader · error
CustomData envelope type '{envelope_type_name}' does not mat
Error message
CustomData envelope type '{envelope_type_name}' does not match message type '{custom_type_name}' What it means
CustomData payloads are decoded by looking up a registered custom data type from the envelope's 'type' field, then verifying the envelope type name equals the registered message type name. If the JSON envelope's 'type' does not match the type the registry resolved for the payload, decoding aborts because the envelope and body would disagree about what data is being carried.
Source
Thrown at crates/common/src/msgbus/external/mod.rs:585
}
}
fn decode_custom_data_value(
custom_type_name: Ustr,
value: &serde_json::Value,
) -> anyhow::Result<Option<CustomData>> {
let Some(data) = deserialize_custom_from_json(custom_type_name.as_str(), value)? else {
log::warn!(
"External custom payload type '{custom_type_name}' is not registered for inbound republishing"
);
return Ok(None);
};
let envelope_type_name = value
.get("type")
.and_then(serde_json::Value::as_str)
.context("CustomData JSON missing 'type' field")?;
anyhow::ensure!(
envelope_type_name == custom_type_name.as_str(),
"CustomData envelope type '{envelope_type_name}' does not match message type '{custom_type_name}'"
);
let Data::Custom(custom) = data else {
anyhow::bail!("CustomData registry returned non-custom data");
};
Ok(Some(custom))
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Ensure the JSON 'type' field exactly equals the custom data class name (to_string of the registered type)
- Re-serialize/re-stamp old persisted messages after renaming a custom data type
- Check for case or namespace differences between the envelope 'type' and the registered type name
- Verify the CustomData registration (registry mapping) points at the same type used to publish
Example fix
// before
let msg = json!({"type": "Quotes", "data": body});
// after (custom type registered as "QuoteTick")
let msg = json!({"type": "QuoteTick", "data": body}); Defensive patterns
Strategy: validation
Validate before calling
def assert_envelope_matches(msg: dict, registered_type: str) -> None:
t = msg.get("type")
if not isinstance(t, str) or not t:
raise ValueError("CustomData JSON missing 'type' field")
if t != registered_type:
raise ValueError(f"envelope type '{t}' != registered '{registered_type}'") Type guard
def envelope_matches(msg: dict, expected: str) -> bool:
return isinstance(msg, dict) and msg.get("type") == expected Try / catch
try:
data = decode_custom_data_payload(json_bytes)
except ValueError as e:
log.error(f"CustomData decode failed: {e}")
metrics.decode_mismatch.inc()
return None Prevention
- Derive the envelope 'type' programmatically from type(custom).__name__ instead of hand-writing it
- Keep a registry test that round-trips every custom data type through serialize/decode
- When renaming custom data classes, migrate persisted messages and bump a schema version
- Watch for casing/namespace drift between publishers in different languages
When it happens
Trigger: Calling decode_custom_data_payload on JSON whose 'type' string differs from the custom data type name registered for the message; e.g. publishing {'type': 'MyIndicator', ...} while the payload registers/decodes as 'MyOtherType', or type names changed between versions.
Common situations: Renaming a custom data class after persisting messages, publishing with a hand-written 'type' string that has a typo or wrong casing, cross-version replay where the custom type was renamed, or registering the wrong custom type for a topic.
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
- JSON does not represent CustomData
- Python object has no to_json() method or __dict__ attribute
- Instances must have encode_record_batch_py method
- Expected {}, was different type
- Failed to serialize data_type for persistence: {e}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/14f6f7d601ed76c6.
Report an issue: GitHub.