{"record":{"id":"63cb091e1dd8045e","repo":"nautechsystems/nautilus_trader","slug":"error-to-string","errorCode":null,"errorMessage":"error.to_string()","messagePattern":"error\\.to_string\\(\\)","errorType":"exception","errorClass":"DydxError::Nautilus","httpStatus":null,"severity":"error","filePath":"crates/adapters/dydx/src/execution/broadcaster.rs","lineNumber":247,"sourceCode":"            if e.is_sequence_mismatch() {\n                // Set flag so next attempt will resync\n                needs_resync_for_retry.store(true, Ordering::SeqCst);\n                log::warn!(\"Sequence mismatch detected, will resync and retry\");\n                true\n            } else if e.is_transient() {\n                // Also resync on transient errors (timeout, unavailable).\n                // Without this, each retry allocates a NEW sequence, causing drift\n                // (e.g., timeout → alloc 314, timeout → alloc 315, then sequence mismatch).\n                needs_resync_for_retry.store(true, Ordering::SeqCst);\n                log::warn!(\"Transient error detected, will resync and retry: {e}\");\n                true\n            } else {\n                false\n            }\n        };\n\n        let create_error =\n            |error: RetryError| DydxError::Nautilus(anyhow::anyhow!(error.to_string()));\n\n        // Permit is held throughout retry loop, released when _permit drops\n        let result = self\n            .retry_manager\n            .invocation(operation_name, operation, should_retry, create_error)\n            .execute()\n            .await;\n\n        if let Err(ref e) = result\n            && (e.is_transient() || e.is_sequence_mismatch())\n        {\n            log::error!(\"Broadcast exhausted retries: operation={operation_name}, error={e}\");\n        }\n\n        result\n    }\n\n    /// Broadcasts a short-term order transaction without sequence management.","sourceCodeStart":229,"sourceCodeEnd":265,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/dydx/src/execution/broadcaster.rs#L229-L265","documentation":"After exhausting retry attempts, `broadcast_with_retry` converts the retry manager's `RetryError` into a `DydxError::Nautilus` using the error's string form. This is the terminal 'broadcast failed after all retries' error: every attempt at the dYdX broadcast operation failed (e.g. sequence mismatches, HTTP/submit failures) and the retry policy gave up.","triggerScenarios":"Calling `broadcast_with_retry` where `retry_manager.invocation(...).execute()` returns `RetryError` after exhausting attempts — persistent sequence mismatch, repeated node/API failures, or non-retryable errors surfaced by `should_retry`.","commonSituations":"Sequence/account number desync after a restart with stale sequence state, dYdX node or indexer outage, invalid transaction rejected by the node on every attempt, or network partition during bursts of orders.","solutions":["Read the inner `error.to_string()` to identify the root cause (sequence mismatch vs API error)","On sequence errors, resync the account sequence (fresh account/query) before broadcasting again","Check dYdX node/indexer connectivity and RPC endpoint health","Validate the transaction contents (gas, fees, memo) if the node rejected it on every attempt","Increase retry budget/backoff for transient network conditions if attempts were exhausted too fast"],"exampleFix":"// before\nlet tx_hash = broadcaster.broadcast_with_retry(\"place_order\", op).await?; // fails with RetryError\n// after\nmatch broadcaster.broadcast_with_retry(\"place_order\", op).await {\n    Ok(h) => Ok(h),\n    Err(e) if e.to_string().contains(\"sequence mismatch\") => {\n        broadcaster.resync_sequence().await?;\n        broadcaster.broadcast_with_retry(\"place_order\", op).await\n    }\n    Err(e) => Err(e),\n}","handlingStrategy":"retry","validationCode":"// Check sequence state freshness before broadcasting\nbroadcaster.ensure_sequence_fresh().await?;","typeGuard":"fn is_sequence_mismatch(e: &DydxError) -> bool { e.to_string().contains(\"sequence mismatch\") }","tryCatchPattern":"match broadcaster.broadcast_with_retry(op_name, op).await {\n    Ok(h) => Ok(h),\n    Err(e) if is_sequence_mismatch(&e) => { broadcaster.resync_sequence().await?; broadcaster.broadcast_with_retry(op_name, op).await }\n    Err(e) => Err(e),\n}","preventionTips":["Keep account sequence state in sync across restarts","Use exponential backoff and adequate retry budgets","Monitor node/indexer health before and during trading","Log the inner RetryError string for root-cause triage"],"tags":["retry","broadcast","network","sequence","dydx"],"backgroundTag":"api-request-failed","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}