{"record":{"id":"362edf42c0e247b7","repo":"nautechsystems/nautilus_trader","slug":"instrument-is-in-pre-open-state","errorCode":null,"errorMessage":"instrument is in pre-open state","messagePattern":"instrument is in pre-open state","errorType":"exception","errorClass":"OKXInstrumentDefinitionError","httpStatus":null,"severity":"warning","filePath":"crates/adapters/okx/src/http/client.rs","lineNumber":2620,"sourceCode":"            params.inst_id(symbol);\n\n            let params = params.build().map_err(|e| anyhow::anyhow!(e))?;\n\n            self.inner\n                .get_instruments(params)\n                .await\n                .map_err(|e| anyhow::anyhow!(e))?\n        };\n\n        let raw_inst = resp\n            .first()\n            .ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;\n\n        // Skip pre-open instruments which have incomplete/empty field values\n        if raw_inst.state == OKXInstrumentStatus::Preopen {\n            return Err(OKXInstrumentDefinitionError::new(\n                symbol,\n                anyhow::anyhow!(\"instrument is in pre-open state\"),\n            )\n            .into());\n        }\n\n        let fee_rate_opt = {\n            let fee_params = GetTradeFeeParams {\n                inst_type: instrument_type,\n                uly: None,\n                inst_family: None,\n            };\n\n            match self.inner.get_trade_fee(fee_params).await {\n                Ok(rates) => rates.into_iter().next(),\n                Err(OKXHttpError::MissingCredentials) => {\n                    log::debug!(\"Missing credentials for fee rates, using None\");\n                    None\n                }\n                Err(e) => {","sourceCodeStart":2602,"sourceCodeEnd":2638,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/okx/src/http/client.rs#L2602-L2638","documentation":"A deliberate lookup failure raised when the requested instrument's OKX state is Preopen. Pre-open instruments have incomplete or empty metadata fields (e.g. unset tick size or lot size), so parsing them would produce an invalid instrument; the library refuses and wraps the reason in OKXInstrumentDefinitionError with the symbol.","triggerScenarios":"Requesting an instrument definition (request_instrument) whose OKX response has state == Preopen, typically for newly listed contracts (futures/options/swaps) that are listed before trading opens.","commonSituations":"Subscribing to or loading a brand-new contract on/just after listing day; enumerating all instruments of a type and hitting one in pre-open; stale cached listings referencing not-yet-live contracts.","solutions":["Wait until the instrument's pre-open interval ends and its state becomes Live, then retry the lookup.","Filter out Preopen-state instruments when enumerating instrument lists (the bulk loader already skips them).","Handle OKXInstrumentDefinitionError for this symbol gracefully and continue with other instruments.","Poll periodically until the instrument definition resolves successfully."],"exampleFix":"// before\nlet instrument = client.request_instrument(symbol)?;\n// after\nlet instrument = match client.request_instrument(symbol) {\n    Ok(inst) => inst,\n    Err(e) if e.to_string().contains(\"pre-open\") => {\n        log::warn!(\"{symbol} is pre-open; deferring\");\n        return Ok(None);\n    }\n    Err(e) => return Err(e.into()),\n};","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"fn is_preopen_error(err: &anyhow::Error) -> bool {\n    err.to_string().contains(\"pre-open state\")\n}","tryCatchPattern":"match client.request_instrument(symbol).await {\n    Ok(inst) => Ok(Some(inst)),\n    Err(e) if e.to_string().contains(\"pre-open\") => {\n        log::info!(\"{symbol} pre-open; retry later\");\n        Ok(None)\n    }\n    Err(e) => Err(e.into()),\n}","preventionTips":["When loading all instruments of a type, filter state == Preopen before parsing.","Defer newly listed contracts until their pre-open window ends.","Schedule periodic re-lookup for instruments that were pre-open.","Treat this error as expected/recoverable, not fatal, in bulk loaders."],"tags":["okx","instrument-state","preopen","instrument-definition"],"backgroundTag":"invalid-state-transition","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"}