nautechsystems/nautilus_trader · error
Lighter funding-rate requests require a perpetual instrument
Error message
Lighter funding-rate requests require a perpetual instrument: {instrument_id} What it means
Funding-rate requests in the Lighter adapter are only valid for perpetual instruments. The adapter looks up the instrument and asserts it is a CryptoPerpetual before issuing the HTTP funding-rate request; any other instrument type (spot, etc.) is rejected.
Source
Thrown at crates/adapters/lighter/src/data/mod.rs:1697
Err(e) => {
log::error!("Lighter trades request failed for {instrument_id}: {e}");
}
}
});
Ok(())
}
fn request_funding_rates(&self, request: RequestFundingRates) -> anyhow::Result<()> {
let instrument_id = request.instrument_id;
log::debug!("Requesting Lighter funding rates for {instrument_id}");
let instrument = self
.instruments
.get_cloned(&instrument_id)
.ok_or_else(|| InstrumentLookupError::not_found(instrument_id))?;
anyhow::ensure!(
matches!(instrument, InstrumentAny::CryptoPerpetual(_)),
"Lighter funding-rate requests require a perpetual instrument: {instrument_id}",
);
let http = self.http_client.clone();
let sender = self.data_sender.clone();
let request_id = request.request_id;
let client_id = request.client_id.unwrap_or(self.client_id);
let start = request.start;
let end = request.end;
let limit = request.limit.map(|n| n.get());
let start_nanos = datetime_to_unix_nanos(start);
let end_nanos = datetime_to_unix_nanos(end);
let params = request.params;
let clock = self.clock;
self.spawn_task(async move {
match httpView on GitHub (pinned to 18893faf8b)
Solutions
- Use a perpetual instrument ID (e.g. ending in -PERP) for funding-rate requests.
- Verify which instruments were loaded/registered by the client — funding is defined only for perps.
- Check your config/instrument catalog so the requested ID maps to a CryptoPerpetual.
- If you genuinely need funding-like data for another product, confirm whether the venue even provides it.
Example fix
// before
client.request_funding_rates(RequestFundingRates::new(InstrumentId::from("ETH-USDC.LIGHTER")));
// after
client.request_funding_rates(RequestFundingRates::new(InstrumentId::from("ETH-USDC-PERP.LIGHTER"))); Defensive patterns
Strategy: validation
Validate before calling
if !instrument_id.to_string().ends_with("-PERP") {
return Err(anyhow!("funding rates require a perpetual instrument: {instrument_id}"));
} Type guard
fn is_perp(inst: &InstrumentAny) -> bool {
matches!(inst, InstrumentAny::CryptoPerpetual(_))
} Try / catch
match client.request_funding_rates(req).await {
Err(e) if e.to_string().contains("require a perpetual instrument") => {
log::warn!("skipping funding-rate request for non-perp {id}");
}
r => r?,
} Prevention
- Only request funding for instrument IDs ending in -PERP.
- Validate instrument type against the loaded catalog before requesting.
- Keep spot and perp instrument IDs clearly separated in config.
When it happens
Trigger: Calling request_funding_rates() with an instrument_id that resolves to a non-perpetual instrument (e.g. a spot instrument), or with an instrument_id registered as something other than InstrumentAny::CryptoPerpetual.
Common situations: Requesting funding rates for a spot pair by mistake; a misconfigured instrument ID that matches a spot market instead of the -PERP market.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Funding rates are only available for Derive perpetual instru
- Unsupported `OrderSide` for Binance: {value:?}
- invalid OrderSide: must be Buy or Sell, was {side}
- Chart function must be callable, was {type(f)}
- Chart function must be callable, was {type(func)}
AI-assisted analysis of nautechsystems/nautilus_trader@18893faf8b (2026-09-08).
Data as JSON: /api/errors/42f4f1f701699816.
Report an issue: GitHub.