{"record":{"id":"18272953480969f8","repo":"nautechsystems/nautilus_trader","slug":"bybit-api-error","errorCode":null,"errorMessage":"Bybit API error {}: {}","messagePattern":"Bybit API error (.+?): (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/http/parse.rs","lineNumber":31,"sourceCode":"//  limitations under the License.\n// -------------------------------------------------------------------------------------------------\n\n//! Parsing functions for Bybit HTTP API responses.\n\nuse serde::de::DeserializeOwned;\n\nuse super::models::{\n    BybitInstrumentInverseResponse, BybitInstrumentLinearResponse, BybitInstrumentOptionResponse,\n    BybitInstrumentSpotResponse, BybitKlinesResponse, BybitServerTimeResponse,\n    BybitTickersLinearResponse, BybitTickersOptionResponse, BybitTickersSpotResponse,\n    BybitTradesResponse,\n};\nuse crate::common::models::BybitResponse;\n\nfn parse_response<T: DeserializeOwned>(data: &[u8]) -> anyhow::Result<BybitResponse<T>> {\n    let response = serde_json::from_slice::<BybitResponse<T>>(data)?;\n    if response.ret_code != 0 {\n        anyhow::bail!(\n            \"Bybit API error {}: {}\",\n            response.ret_code,\n            response.ret_msg\n        );\n    }\n    Ok(response)\n}\n\n/// Parses a Bybit server time response from raw JSON bytes.\n///\n/// # Errors\n///\n/// Returns an error if deserialization or validation fails.\npub fn parse_server_time_response(data: &[u8]) -> anyhow::Result<BybitServerTimeResponse> {\n    parse_response(data)\n}\n\n/// Parses a Bybit spot instruments response from raw JSON bytes.","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/http/parse.rs#L13-L49","documentation":"Every Bybit HTTP response carries retCode/retMsg; retCode 0 means success. parse_response deserializes the envelope and, for any non-zero retCode, bails with a formatted error containing the venue code and message — this is how Bybit API-level rejections surface in the adapter.","triggerScenarios":"Any API call whose response envelope has retCode != 0, e.g. invalid API key (-2015), rate limit (10006), invalid symbol, insufficient balance, or permission errors, across server-time, instruments, and tickers endpoints.","commonSituations":"Expired or wrongly-scoped API keys; hitting IP rate limits; querying symbols that do not exist for the product type; Bybit maintenance windows returning error codes.","solutions":["Read the ret_code in the error message and look it up in Bybit's API docs for the precise cause","Verify API key/secret and key permissions (read/trade) for the account","Slow down requests or add backoff if retCode indicates rate limiting (10006)","Fix the request parameters (symbol, category, product type) per the ret_msg"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// cannot be pre-validated; handle after each call\n// check ret_code mapping in Bybit API docs","typeGuard":null,"tryCatchPattern":"match client.parse_server_time_response(&body) {\n    Err(e) if e.to_string().contains(\"Bybit API error\") => {\n        let code = extract_ret_code(&e.to_string());\n        match code {\n            10006 => backoff_and_retry().await?,   // rate limit\n            -2015 => return Err(anyhow!(\"check API key permissions\")),\n            _ => return Err(e),\n        }\n    }\n    other => other?,\n}","preventionTips":["Map Bybit ret_codes to actionable handling in your error layer","Use API keys with correct scopes and valid expiry","Apply backoff for rate-limit codes","Validate symbol/category parameters against the instruments endpoint before trading calls"],"tags":["bybit","api-error","ret-code"],"backgroundTag":"api-error-response","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"}