nautechsystems/nautilus_trader · error
AccountId contains '-'
Error message
AccountId contains '-'
What it means
`AccountId::get_issuer` extracts the venue prefix of an account ID of the form `ISSUER-NUMBER` (e.g. `SIM-001`). It panics with "AccountId contains '-'" when the internal string contains no hyphen, meaning the ID was constructed bypassing validation (via `from_str_unchecked` or raw/new constructors) or the format contract changed. Well-formed AccountIds validated through the parser always contain a hyphen.
Source
Thrown at crates/model/src/identifiers/account_id.rs:115
#[must_use]
pub fn inner(&self) -> Ustr {
self.0
}
/// Returns the inner identifier value as a string slice.
#[must_use]
pub fn as_str(&self) -> &str {
self.0.as_str()
}
/// Returns the account issuer for this identifier.
///
/// # Panics
///
/// Panics if the internal ID does not contain a hyphen separator.
#[must_use]
pub fn get_issuer(&self) -> Venue {
Venue::from_str_unchecked(self.0.split_once('-').expect("AccountId contains '-'").0)
}
/// Returns the account ID assigned by the issuer.
///
/// # Panics
///
/// Panics if the internal ID does not contain a hyphen separator.
#[must_use]
pub fn get_issuers_id(&self) -> &str {
self.0.split_once('-').expect("AccountId contains '-'").1
}
}
impl Debug for AccountId {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\"{}\"", self.0)
}
}View on GitHub (pinned to 18893faf8b)
Solutions
- Fix the account ID string so it includes the issuer hyphen separator, e.g. "BINANCE-001".
- Construct AccountId via the checked `from_str`/parser path so malformed IDs are rejected at creation instead of panicking later.
- Audit where the ID originates (config, database, adapter) and correct the formatting there.
- If you must inspect arbitrary strings, split on '-' yourself and handle None instead of using get_issuer.
Example fix
// before
let id = AccountId::new("SIM001");
let issuer = id.get_issuer(); // panics
// after
let id = AccountId::from_str("SIM-001").expect("valid account id");
let issuer = id.get_issuer(); // Venue("SIM") Defensive patterns
Strategy: validation
Validate before calling
// Rust caller
fn safe_issuer(id: &AccountId) -> Option<Venue> {
id.as_str().split_once('-').map(|(issuer, _)| Venue::from_str_unchecked(issuer))
} Type guard
fn is_well_formed_account_id(s: &str) -> bool {
s.split_once('-').map_or(false, |(issuer, num)| !issuer.is_empty() && !num.is_empty())
} Try / catch
// AccountId methods panic rather than return Result; validate first
if is_well_formed_account_id(id.as_str()) {
let issuer = id.get_issuer();
} else {
log::error!("malformed account id: {}", id);
} Prevention
- Always construct AccountId via the checked from_str/parser path.
- Enforce the ISSUER-NUMBER convention when importing IDs from external systems.
- Add a format assertion at ingestion boundaries (config load, DB read).
When it happens
Trigger: Calling get_issuer() on an AccountId built with `AccountId::new`/unsafe unchecked constructors from a string lacking a hyphen, e.g. "SIM001" instead of "SIM-001".
Common situations: Deserializing account IDs from external config/CSV/databases with a different naming convention, hand-crafted IDs in tests, or upstream venue renames dropping the separator.
Understand the failure class
Background: "invalid id" errors: invalid identifier format — why libraries reject IDs before lookup, and how to fix them — this error's family across 37 libraries.
Related errors
- in-flight mutex poisoned
- wallet balance mutex poisoned
- instrument update lock poisoned
- rate limiter decision lock poisoned
- Unsupported blockchain {blockchain} for RPC connection
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/96d3f68e1b4dd01a.
Report an issue: GitHub.