{"record":{"id":"4366ce118f0c7086","repo":"nautechsystems/nautilus_trader","slug":"lighter-transaction-lookup-returned-client-order-i","errorCode":null,"errorMessage":"Lighter transaction lookup returned client_order_index {} for acknowledged create {client_order_index}","messagePattern":"Lighter transaction lookup returned client_order_index (.+?) for acknowledged create (.+?)","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/adapters/lighter/src/execution.rs","lineNumber":3381,"sourceCode":"fn validate_acked_create_tx(\n    tx: &crate::http::models::LighterTx,\n    account_index: i64,\n    api_key_index: u8,\n    client_order_index: i64,\n    nonce: i64,\n    tx_hash: &str,\n) -> anyhow::Result<()> {\n    anyhow::ensure!(\n        tx_hash_matches(&tx.hash, tx_hash)\n            && tx.tx_type == LighterTxType::CreateOrder as u8\n            && tx.account_index == account_index\n            && tx.api_key_index == api_key_index\n            && tx.nonce == nonce,\n        \"Lighter transaction lookup did not match acknowledged create identity\",\n    );\n    let info: AckedCreateTxInfo = serde_json::from_str(&tx.info)\n        .context(\"failed to parse Lighter create transaction info\")?;\n    anyhow::ensure!(\n        info.client_order_index == client_order_index,\n        \"Lighter transaction lookup returned client_order_index {} for acknowledged create {client_order_index}\",\n        info.client_order_index,\n    );\n    Ok(())\n}\n\nfn tx_hash_matches(left: &str, right: &str) -> bool {\n    let left = left\n        .strip_prefix(\"0x\")\n        .or_else(|| left.strip_prefix(\"0X\"))\n        .unwrap_or(left);\n    let right = right\n        .strip_prefix(\"0x\")\n        .or_else(|| right.strip_prefix(\"0X\"))\n        .unwrap_or(right);\n    left.eq_ignore_ascii_case(right)\n}","sourceCodeStart":3363,"sourceCodeEnd":3399,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/adapters/lighter/src/execution.rs#L3363-L3399","documentation":"After the transaction identity checks pass, validate_acked_create_tx parses the tx info JSON into AckedCreateTxInfo and asserts its client_order_index equals the client_order_index of the order being verified. This guards against an exchange-side race or bug where the matched create transaction carries a different client order index than the locally acknowledged one.","triggerScenarios":"The tx lookup matched the create identity (hash/type/account/key/nonce) but the decoded tx.info contains a client_order_index different from the order's acknowledged client_order_index — e.g. info parsed from a wrong transaction or the acknowledgement recorded the wrong index.","commonSituations":"Client order index conversion issues (i64 overflow/offset between local IDs and exchange IDs); submitting with a regenerated client_order_index after retry while the old acknowledgement record is reused; duplicate submits where the matched tx is a prior attempt.","solutions":["Confirm the client_order_index used when signing the create tx equals the order's client_order_id-derived index and matches what was stored at acknowledgement","Retry the lookup/parse after a delay in case info JSON was stale","If the exchange returns a different index, re-submit the create with a fresh, correctly derived client_order_index and re-acknowledge"],"exampleFix":"// before\nensure!(info.client_order_index == client_order_index, ...);\n// after\nif info.client_order_index != client_order_index {\n    log::warn!(\"create tx index {} != acked {}\", info.client_order_index, client_order_index);\n    return Err(...);\n}","handlingStrategy":"validation","validationCode":"if info.client_order_index != expected_client_order_index {\n    return Err(anyhow!(\"create tx index mismatch\"));\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Derive client_order_index once and reuse it in signing, acknowledgement, and validation","Avoid reusing stale acknowledgement records across retries","Check for i64 index conversion offsets between local and exchange IDs"],"tags":["rust","lighter","blockchain","id-mismatch"],"backgroundTag":"internal-invariant-violation","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"}