{"record":{"id":"e6f78931b21f50b1","repo":"nautechsystems/nautilus_trader","slug":"funding-rates-only-available-for-perpetuals-not","errorCode":null,"errorMessage":"Funding rates only available for perpetuals, not {instrument_id}","messagePattern":"Funding rates only available for perpetuals, not (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/bybit/src/data.rs","lineNumber":1135,"sourceCode":"        );\n        Ok(())\n    }\n\n    fn subscribe_funding_rates(&mut self, cmd: SubscribeFundingRates) -> anyhow::Result<()> {\n        let instrument_id = cmd.instrument_id;\n        let product_type = self\n            .get_product_type_for_instrument(instrument_id)\n            .unwrap_or(BybitProductType::Linear);\n\n        if product_type == BybitProductType::Spot || product_type == BybitProductType::Option {\n            anyhow::bail!(\"Funding rates not available for {product_type:?} instruments\");\n        }\n\n        let guard = self.instruments.load();\n        if let Some(instrument) = guard.get(&instrument_id)\n            && !matches!(instrument, InstrumentAny::CryptoPerpetual(_))\n        {\n            anyhow::bail!(\"Funding rates only available for perpetuals, not {instrument_id}\");\n        }\n\n        let mut should_subscribe = false;\n        self.ticker_subs.rcu(|m| {\n            let entry = m.entry(instrument_id).or_default();\n            should_subscribe = entry.is_empty();\n            entry.insert(\"funding\");\n        });\n\n        if should_subscribe {\n            let ws = self\n                .get_ws_client_for_product(product_type)\n                .context(\"no WebSocket client for product type\")?\n                .clone();\n\n            self.spawn_ws(\n                async move {\n                    ws.subscribe_ticker(instrument_id)","sourceCodeStart":1117,"sourceCodeEnd":1153,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/bybit/src/data.rs#L1117-L1153","documentation":"Beyond the product-type check, subscribe_funding_rates verifies that a cached instrument matching the requested ID is actually a CryptoPerpetual. If the instrument is loaded in the client's cache but is another type (spot, option, futures contract), the subscription is rejected because funding rates are a perpetual-only concept in this adapter.","triggerScenarios":"subscribe_funding_rates called with an instrument_id present in the client's instrument cache whose InstrumentAny variant is not CryptoPerpetual — e.g. an expiring future or an option instrument registered under that ID.","commonSituations":"Subscribing to funding rates for dated futures or options assuming perpetual-like behavior; instruments cached with a wrong/generic type after a load; mistyped instrument ID strings that resolve to a non-perpetual symbol.","solutions":["Use the exact perpetual instrument ID (CryptoPerpetual) when subscribing to funding rates","Verify what instrument is registered under that ID in the client cache","Load/refresh the correct perpetual instrument before subscribing","Filter non-perpetual instruments out of automated funding-rate subscription loops"],"exampleFix":"// before\nsubscribe_funding_rates(\"BTCUSDT-27SEP26\".into())? // dated future: bails\n// after\nsubscribe_funding_rates(\"BTCUSDT-PERP\".into())? // CryptoPerpetual","handlingStrategy":"validation","validationCode":"fn is_perp_cached(client: &BybitDataClient, id: InstrumentId) -> bool {\n    client.instruments.load().get(&id)\n        .map(|i| matches!(i, InstrumentAny::CryptoPerpetual(_)))\n        .unwrap_or(false)\n}","typeGuard":"fn is_perpetual(inst: &InstrumentAny) -> bool {\n    matches!(inst, InstrumentAny::CryptoPerpetual(_))\n}","tryCatchPattern":"if !is_perpetual_cached(&client, id) {\n    log::debug!(\"{id} is not a perpetual; skipping funding subscription\");\n} else {\n    client.subscribe_funding_rates(cmd)?;\n}","preventionTips":["Ensure the perpetual instrument is loaded into the client cache before subscribing","Verify the InstrumentAny variant registered under each ID","Auto-discover perpetuals from the instruments response rather than hardcoding IDs"],"tags":["bybit","funding-rates","instrument-type","perpetual"],"backgroundTag":"unsupported-operation","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}