{"record":{"id":"75650a1150738493","repo":"nautechsystems/nautilus_trader","slug":"e-75650a","errorCode":null,"errorMessage":"{e}","messagePattern":"\\{e\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/betfair/src/provider.rs","lineNumber":282,"sourceCode":"/// 1. Fetches the navigation tree via `send_navigation`\n/// 2. Flattens and filters to matching market IDs\n/// 3. Batches market IDs (max 50 per request)\n/// 4. Calls `listMarketCatalogue` for each batch\n/// 5. Parses results into [`InstrumentAny`] via `parse_market_catalogue`\n///\n/// # Errors\n///\n/// Returns an error if any API request fails or instrument parsing fails.\npub async fn load_instruments(\n    client: &BetfairHttpClient,\n    filter: &NavigationFilter,\n    currency: Currency,\n    min_notional: Option<Money>,\n) -> anyhow::Result<Vec<InstrumentAny>> {\n    let navigation: Navigation = client\n        .send_navigation()\n        .await\n        .map_err(|e| anyhow::anyhow!(\"{e}\"))?;\n\n    let all_markets = flatten_navigation(&navigation);\n\n    let filtered: Vec<&FlattenedMarket> =\n        all_markets.iter().filter(|m| filter.matches(m)).collect();\n\n    log::debug!(\"Found {} markets matching filter\", filtered.len());\n\n    let market_ids: Vec<MarketId> = filtered\n        .iter()\n        .filter_map(|m| m.market_id.clone())\n        .collect::<AHashSet<_>>()\n        .into_iter()\n        .collect();\n\n    let time_range =\n        if filter.min_market_start_time.is_some() || filter.max_market_start_time.is_some() {\n            Some(TimeRange {","sourceCodeStart":264,"sourceCodeEnd":300,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/a4b06ed870971b5671d12754ea138a3ab99b1dec/crates/adapters/betfair/src/provider.rs#L264-L300","documentation":"load_instruments fetches Betfair's navigation data via send_navigation (the listNavigationData REST endpoint) and this wraps any failure of that call as {e}. The wrapped BetfairHttpError is typically a missing/invalid session token, an application key mismatched to the endpoint environment, a network failure, or a decode error on the navigation JSON.","triggerScenarios":"Running the instrument provider's load path (load_instruments) before login completed, with an app key lacking the right product scope, or when the navigation endpoint is unreachable from the host.","commonSituations":"Delayed vs live app key mismatch; provider warm-up with expired credentials; proxy/firewall blocking the navigation URL.","solutions":["Confirm login succeeds and a session token exists before loading instruments.","Verify the application key matches the environment of the configured endpoints.","Check network/proxy reachability of the navigation URL.","Retry the load — transient failures clear on the next attempt."],"exampleFix":null,"handlingStrategy":"retry","validationCode":"// verify session readiness before heavy instrument loads\nif !http_client.is_connected().await {\n    http_client.connect().await?;\n}","typeGuard":null,"tryCatchPattern":"match load_instruments(&client, &filter, currency, min_notional).await {\n    Ok(instruments) => { /* store */ }\n    Err(e) => {\n        log::warn!(\"navigation load failed, retrying: {e}\");\n        tokio::time::sleep(Duration::from_secs(5)).await;\n        // retry once; escalate on repeated failure\n    }\n}","preventionTips":["Confirm login and app-key/environment pairing before loading instruments.","Run instrument loads during off-peak or after connectivity checks in restricted networks.","Cache loaded instruments so a failed load does not block startup."],"tags":["betfair","instrument-provider","navigation","http"],"backgroundTag":"http-request-failed","analyzedSha":"a4b06ed870971b5671d12754ea138a3ab99b1dec","analyzedAt":"2026-08-16T22:54:50.089Z","schemaVersion":2},"datasetVersion":"2026-08-16T23:17:17.608Z"}