{"record":{"id":"0944dd8758ffc988","repo":"nautechsystems/nautilus_trader","slug":"signer-not-initialized-connect-the-client-first","errorCode":null,"errorMessage":"Signer not initialized; connect the client first","messagePattern":"Signer not initialized; connect the client first","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/adapters/blockchain/src/execution/client.rs","lineNumber":797,"sourceCode":"            );\n        }\n\n        Ok(pool)\n    }\n\n    /// Builds the shared transaction executor from the connected client state.\n    ///\n    /// # Errors\n    ///\n    /// Returns an error if no durable store is configured or the signer is not initialized.\n    fn transaction_executor(&self) -> anyhow::Result<TransactionExecutor> {\n        let database = self.cache.database.clone().ok_or_else(|| {\n            anyhow::anyhow!(\"No durable store configured; refusing to submit a transaction\")\n        })?;\n        let signer = self\n            .signer\n            .clone()\n            .ok_or_else(|| anyhow::anyhow!(\"Signer not initialized; connect the client first\"))?;\n\n        Ok(TransactionExecutor {\n            http_rpc_client: self.http_rpc_client.clone(),\n            database,\n            signer,\n            in_flight: Arc::clone(&self.in_flight),\n            wallet_balance: Arc::clone(&self.wallet_balance),\n            account_id: self.core.account_id,\n            wallet_address: self.wallet_address,\n            chain_id: self.chain.chain_id,\n            max_fee_per_gas_wei: self.config.max_fee_per_gas_wei,\n            base_fee_buffer_bps: self.config.base_fee_buffer_bps,\n            gas_limit: self.config.gas_limit,\n            gas_buffer_bps: self.config.gas_buffer_bps,\n            receipt_timeout: receipt_timeout(self.transaction_limits.receipt_timeout_secs),\n            receipt_max_polls: receipt_max_polls(self.transaction_limits.receipt_timeout_secs),\n        })\n    }","sourceCodeStart":779,"sourceCodeEnd":815,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/2114cf6f761429e0adb5ca9596fcd7b895b16011/crates/adapters/blockchain/src/execution/client.rs#L779-L815","documentation":"transaction_executor (crates/adapters/blockchain/src/execution/client.rs:797) requires an initialized signer; self.signer is populated only during connect(), which loads the private key from config.signer_private_key_env, validates it as hex, and verifies the derived address matches the configured wallet address. disconnect() clears the signer, and connect() itself resets it to None if any post-signer step (execution reconciliation, wallet balance refresh) fails. The error therefore means a signing operation ran outside a fully established connection, and the root cause is usually an earlier connect failure or a missing call.","triggerScenarios":"Calling wrap/approve/submit_order before connect(); calling them after disconnect(); connect() failed at reconciliation or refresh_wallet_balances (both reset signer to None and return the underlying error) and the caller ignored the failure and proceeded.","commonSituations":"Fire-and-forget startup that never awaits connect(); the signer env var unset or invalid, or its derived address mismatching wallet_address, causing connect to bail earlier; a disconnect triggered mid-session (stop command) followed by a late order submission.","solutions":["Await client.connect() and check it returned Ok before issuing any transactional operation.","If connect failed, read the original error it returned - signer-private-key-env not set, invalid hex key, wallet address mismatch, or reconciliation/balance failure are the usual causes.","Set the env var named by config.signer_private_key_env to the hex private key whose address equals the configured wallet address.","Do not submit after disconnect(); reconnect first."],"exampleFix":"// before\nlet mut client = BlockchainExecutionClient::new(/* ... */);\nclient.wrap(amount_wei).await?; // error: signer not initialized\n\n// after\nlet mut client = BlockchainExecutionClient::new(/* ... */);\nclient.connect().await?;      // loads signer from env, reconciles, refreshes balances\nclient.wrap(amount_wei).await?;","handlingStrategy":"validation","validationCode":"// Rust: only submit on a fully connected client\nanyhow::ensure!(\n    client.is_connected(),\n    \"blockchain client not connected; call connect() before submitting\"\n);\n// also confirm the signer env var exists before starting the session\nstd::env::var(&config.signer_private_key_env)\n    .with_context(|| format!(\"set {} before connect\", config.signer_private_key_env))?;","typeGuard":"fn is_signer_uninitialized(e: &anyhow::Error) -> bool {\n    e.to_string().contains(\"Signer not initialized; connect the client first\")\n}","tryCatchPattern":"match client.wrap(amount_wei).await {\n    Ok(hash) => hash,\n    Err(e) if is_signer_uninitialized(&e) => {\n        // lifecycle bug: reconnect, surfacing the original connect() error if any\n        client.connect().await?;\n        client.wrap(amount_wei).await\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Gate every submission path behind an is_connected() assertion.","Always await and check connect()'s result; its error explains why the signer was reset.","Set and validate the signer env var (hex key matching wallet_address) before starting the client.","Treat disconnect() as terminal for the session - never submit afterwards."],"tags":["lifecycle","signer","connection","configuration","rust"],"backgroundTag":"client-not-connected","analyzedSha":"2114cf6f761429e0adb5ca9596fcd7b895b16011","analyzedAt":"2026-08-21T11:28:30.864Z","schemaVersion":2},"datasetVersion":"2026-08-22T04:17:13.399Z"}