nautechsystems/nautilus_trader · error · anyhow::Error
{key} `value` contained invalid characters, was {value}
Error message
{key} `value` contained invalid characters, was {value} What it means
MStr::checked validates that the underlying Ustr for a typed message-topic string contains only valid UTF-8 and none of the wildcard characters `*` or `?`. Topics are pattern-matched internally, so wildcard characters in a stored MStr would corrupt matching; the code bails with this message naming the key type.
Source
Thrown at crates/common/src/msgbus/mstr.rs:55
///
/// - `MStr<Pattern>` - for subscriptions, allows wildcards (`*`, `?`)
/// - `MStr<Topic>` - for publishing, no wildcards
/// - `MStr<Endpoint>` - for direct messages, no wildcards
#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(transparent)]
pub struct MStr<T> {
value: Ustr,
#[serde(skip)]
_marker: std::marker::PhantomData<T>,
}
impl<T> MStr<T> {
#[inline(always)]
fn checked(value: Ustr, key: &str) -> anyhow::Result<Self> {
check_valid_string_utf8(value, stringify!(value))?;
if value.as_bytes().iter().any(|&b| b == b'*' || b == b'?') {
anyhow::bail!("{key} `value` contained invalid characters, was {value}");
}
Ok(Self {
value,
_marker: std::marker::PhantomData,
})
}
}
impl<T> Display for MStr<T> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.value)
}
}
impl<T> Deref for MStr<T> {
type Target = Ustr;
View on GitHub (pinned to 18893faf8b)
Solutions
- Remove `*` and `?` from the string before constructing the MStr.
- Use the wildcard-aware subscribe/pattern API instead of embedding wildcards in a topic value.
- Validate/sanitize user-provided topic config values before creating MStr instances.
Example fix
// before
let topic = MStr::<Topic>::new("data.quotes.*")?;
// after
let topic = MStr::<Topic>::new("data.quotes")?;
// subscribe with pattern instead
msgbus.subscribe_pattern("data.quotes.*", handler); Defensive patterns
Strategy: validation
Validate before calling
def make_mstr(value: str) -> str:
if any(ch in value for ch in "*?"):
raise ValueError(f"topic value must not contain wildcards: {value!r}")
return value Try / catch
match MStr::<Topic>::new(user_value) {
Ok(t) => use(t),
Err(e) => log::warn!("invalid topic string: {e}"),
} Prevention
- Never embed glob wildcards in topic values; use pattern-subscription APIs instead.
- Sanitize config-sourced topic strings at load time.
- Add a unit test that rejects wildcard characters in all topic-building helpers.
When it happens
Trigger: Constructing any MStr<T> typed constructor (e.g. MStr::topic or MStr::endpoint) with a string containing `*` or `?`, or with non-UTF-8 bytes (via check_valid_string_utf8, which raises its own error).
Common situations: Building topics from user-supplied subscription patterns like 'data.quotes.*' instead of subscribing via a wildcard pattern API; config files where glob-style topic filters are pasted into topic fields; copied topic strings including pattern suffixes.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Unsupported `OrderSide` for Binance: {value:?}
- invalid OrderSide: must be Buy or Sell, was {side}
- Chart function must be callable, was {type(f)}
- Chart function must be callable, was {type(func)}
- Chart '{name}' not found.{suggestion_text} Available charts:
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/a2c8936aebb75a72.
Report an issue: GitHub.