nautechsystems/nautilus_trader · error
OrderMessageBuilder not initialized - call connect() first
Error message
OrderMessageBuilder not initialized - call connect() first
What it means
The OrderMessageBuilder converts Nautilus order objects into dYdX protobuf messages and, like the other components, is stored in an Option filled by connect(). If get_execution_components() finds it None when an order/cancel is submitted, this error is thrown. It means the client is being used in a partially or wholly uninitialized state.
Source
Thrown at crates/adapters/dydx/src/execution/mod.rs:844
Arc<OrderMessageBuilder>,
)> {
let tx_manager = self
.tx_manager
.as_ref()
.ok_or_else(|| {
anyhow::anyhow!("TransactionManager not initialized - call connect() first")
})?
.clone();
let broadcaster = self
.broadcaster
.as_ref()
.ok_or_else(|| anyhow::anyhow!("TxBroadcaster not initialized - call connect() first"))?
.clone();
let order_builder = self
.order_builder
.as_ref()
.ok_or_else(|| {
anyhow::anyhow!("OrderMessageBuilder not initialized - call connect() first")
})?
.clone();
Ok((tx_manager, broadcaster, order_builder))
}
fn spawn_task<F>(&self, label: &'static str, fut: F)
where
F: Future<Output = anyhow::Result<()>> + Send + 'static,
{
let future = async move {
if let Err(e) = fut.await {
log::error!("{label}: {e:?}");
}
};
self.spawn_labeled(label, future);
}
View on GitHub (pinned to 18893faf8b)
Solutions
- Call and await connect() fully before trading operations
- Check connect() error path/logs to find why initialization stopped at order_builder
- Recreate the client (or call connect() again) so all three components are initialized
Example fix
// before
let client = DydxExecClient::new(config)?;
tokio::spawn(async move { client.submit_order(order) }); // races connect()
// after
let client = DydxExecClient::new(config)?;
client.connect().await?;
tokio::spawn(async move { client.submit_order(order) }); Defensive patterns
Strategy: try-catch
Validate before calling
if !client.is_connected() {
client.connect().await?;
} Try / catch
match client.submit_order(order).await {
Err(e) if e.to_string().contains("not initialized - call connect()") => {
client.connect().await?;
client.submit_order(order).await?;
}
r => r?,
} Prevention
- Initialize the client in a single startup phase (new -> connect -> trade) and enforce that order in code review
- Recreate the client instead of reusing one whose connect() failed
- Add an integration test that asserts trading calls fail cleanly without connect() and succeed after it
When it happens
Trigger: Calling submit_order, submit_order_list, cancel_order, cancel_all_orders, or batch_cancel_orders before connect() finished; this branch runs only when tx_manager and broadcaster are already set, so connect() failed after initializing them but before the order_builder.
Common situations: Transient failure during connect() leaving later components unset; submitting from a callback that fires before connection completes; reusing a client across a failed reconnect.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- TransactionManager not initialized - call connect() first
- TxBroadcaster not initialized - call connect() first
- Active execution intent {intent_id} was not found
- DataActor {} must be registered before calling `clock_mut()`
- DataActor {} must be registered before calling `clock()` - t
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/dcfc025e0f6fb0e8.
Report an issue: GitHub.