nautechsystems/nautilus_trader · error
Failed to start Lighter data task generation: {e}
Error message
Failed to start Lighter data task generation: {e} What it means
The Lighter data client failed while starting its background WebSocket data task generation during connect(). Any error returned by `tasks.start_generation()` (typically an internal spawn or channel setup failure) is wrapped in this message. It is thrown to abort a partially-completed connect and signals the client could not begin producing market data.
Source
Thrown at crates/adapters/lighter/src/data/mod.rs:984
if self.is_connected()
&& self.tasks.is_open()
&& self.ws_disconnect_handle.is_none()
&& self.ws_handler_retained.is_empty()
{
return Ok(());
}
if !self.tasks.is_open()
|| !self.tasks.is_empty()
|| self.ws_disconnect_handle.is_some()
|| !self.ws_handler_retained.is_empty()
{
self.teardown_partial_connect().await?;
}
if !self.tasks.is_open() {
self.tasks.start_generation().map_err(|e| {
anyhow::anyhow!("Failed to start Lighter data task generation: {e}")
})?;
self.cancellation_token = self.tasks.cancellation_token();
}
let ws_client = self.ws_client.clone();
let setup_guard = TaskGroupGuard::new(&[&self.tasks], move || {
ws_client.begin_shutdown();
});
let instruments = self
.bootstrap_instruments()
.await
.context("failed to bootstrap Lighter instruments")?;
for instrument in instruments {
if let Err(e) = self.data_sender.send(DataEvent::Instrument(instrument)) {
log::warn!("Failed to send instrument: {e}");
}View on GitHub (pinned to 18893faf8b)
Solutions
- Read the wrapped inner error ({e}) to identify the underlying start_generation failure.
- Construct a fresh LighterDataClient instead of reusing one after a failed connect.
- Ensure the async runtime is healthy and not shutting down when connect() is called.
- Update the adapter version in case of a known task-generation bug.
Example fix
// before let client = build_client(); client.connect().await?; // may fail after prior partial connect // after let client = build_client(); // rebuild a fresh client on retry client.connect().await?;
Defensive patterns
Strategy: try-catch
Validate before calling
// Rust: check task group state before connect assert!(!client_is_torn_down, "rebuild client instead of reusing after failed connect");
Try / catch
match client.connect().await {
Err(e) if e.to_string().contains("Failed to start Lighter data task generation") => {
// rebuild a fresh client and retry once
}
r => r?,
} Prevention
- Rebuild data clients instead of reconnecting a failed instance.
- Keep the async runtime alive while connecting clients.
- Keep the adapter updated for task-group fixes.
When it happens
Trigger: Calling connect() on LighterDataClient when the internal task group's start_generation() fails — e.g. a required runtime handle is missing or the task group was already torn down after a prior partial connect failure (note the preceding teardown_partial_connect() call).
Common situations: Reconnecting after a failed connect in the same client instance; running in a runtime that is shutting down; a bug or incompatibility in the task-group infrastructure.
Related errors
- std::mem::take(&mut self.shutdown_errors).join("; ")
- Failed to start Spot public JSON WS bytes task: {e}
- Failed to start Spot public JSON WS handler task: {e}
- WebSocket output receiver not available
- Coinbase WebSocket handler failed: {error}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/0f441211f53d4708.
Report an issue: GitHub.