nautechsystems/nautilus_trader · error

Lighter account detail returned an empty L1 address

Error message

Lighter account detail returned an empty L1 address

What it means

During referral attribution (apply_referral_attribution, invoked from connect), the account detail response must contain a non-empty l1_address; an empty/whitespace-only address means the venue returned incomplete account details, so the adapter aborts rather than minting an auth token with bad identity data.

Source

Thrown at crates/adapters/lighter/src/execution.rs:717

            None
        }
    }

    async fn apply_referral_attribution(
        &self,
        detail: &LighterAccountDetail,
    ) -> anyhow::Result<()> {
        let Some(referral_code) =
            deployment::referral_code(self.config.deployment, self.config.environment)
        else {
            return Ok(());
        };

        let Some(credential) = &self.credential else {
            return Ok(());
        };

        anyhow::ensure!(
            !detail.l1_address.trim().is_empty(),
            "Lighter account detail returned an empty L1 address"
        );

        let auth_token = build_auth_token_for(credential)
            .context("failed to mint Lighter auth token for referral attribution")?;
        let referral_code = Zeroizing::new(referral_code.to_string());

        self.http_client
            .use_referral(&detail.l1_address, referral_code.as_str(), &auth_token)
            .await
            .context("failed to apply Lighter referral code")?;

        log::debug!("Applied Robinhood Chain referral attribution");
        Ok(())
    }

    /// Returns `Ok(true)` if this credential's `api_key_index` is maker-only.

View on GitHub (pinned to 18893faf8b)

Solutions

  1. Verify the account exists and is fully set up on Lighter (check l1 address on the venue).
  2. Check the account detail API response manually for the same account to see if it's empty server-side.
  3. Confirm account_index/credentials point at the intended account.
  4. Retry later if the venue is returning partial data during an incident.
Defensive patterns

Strategy: try-catch

Validate before calling

// after fetching account detail, before connect-time attribution
if detail.l1_address.trim().is_empty() {
    return Err(anyhow!("venue returned empty l1_address; account not provisioned?"));
}

Try / catch

match client.connect().await {
    Err(e) if e.to_string().contains("empty L1 address") => {
        // verify account provisioning, retry later
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling connect() on a LighterExecutionClient with a credential set, where the account-detail API response contains an empty or blank l1_address.

Common situations: Account not fully provisioned on the venue yet; API returning a partial/empty account payload due to venue-side outage; wrong account_index resolving to an empty record.

Understand the failure class

Background: "must not be empty", "cannot be empty" — required-field validation errors across open-source libraries — this error's family across 41 libraries.

Related errors


AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08). Data as JSON: /api/errors/0faf487f9feb0c01. Report an issue: GitHub.