we-promise/sure · warning · Provider::BinancePublic::InvalidSecurityPriceError
No price found for #{symbol} on #{date}
Error message
No price found for #{symbol} on #{date} What it means
Raised by Provider::BinancePublic#fetch_security_price (as InvalidSecurityPriceError, defined as Class.new(Error) at binance_public.rb:6) when fetch_security_prices for a single day succeeds but returns an empty data set. It can also re-raise historical.error first; this specific message fires only when historical.data.blank? for the requested date.
Source
Thrown at app/models/provider/binance_public.rb:185
logo_url: nil,
description: nil,
kind: "crypto",
exchange_operating_mic: exchange_operating_mic
)
end
end
def fetch_security_price(symbol:, exchange_operating_mic:, date:)
with_provider_response do
historical = fetch_security_prices(
symbol: symbol,
exchange_operating_mic: exchange_operating_mic,
start_date: date,
end_date: date
)
raise historical.error if historical.error.present?
raise InvalidSecurityPriceError, "No price found for #{symbol} on #{date}" if historical.data.blank?
historical.data.first
end
end
def fetch_security_prices(symbol:, exchange_operating_mic:, start_date:, end_date:)
with_provider_response do
parsed = parse_ticker(symbol)
raise InvalidSecurityPriceError, "Unsupported Binance ticker: #{symbol}" if parsed.nil?
if parsed[:stablecoin]
next stablecoin_prices(symbol, parsed, start_date, end_date, exchange_operating_mic)
end
binance_pair = parsed[:binance_pair]
display_currency = parsed[:display_currency]
prices = []
cursor = start_dateView on GitHub (pinned to e69894adb9)
Solutions
- Confirm the pair's listing date (first available kline on Binance) and clamp start_date to it.
- Reject future dates before calling: no price can exist for date > Date.today.
- If the price is genuinely missing, fall back to the nearest earlier close or the security's last known price rather than failing.
- Rescue Provider::BinancePublic::InvalidSecurityPriceError per-date so one gap does not abort a range import.
Example fix
# before price = provider.fetch_security_price(symbol: "BTCUSDT", exchange_operating_mic: "BINANCE", date: Date.new(2015, 1, 1)) # after begin price = provider.fetch_security_price(symbol: "BTCUSDT", exchange_operating_mic: "BINANCE", date: date) rescue Provider::BinancePublic::InvalidSecurityPriceError price = nil # or last known close; skip the day instead of aborting the sync end
Defensive patterns
Strategy: fallback
Validate before calling
return if date > Date.today # no price can exist in the future return if listing_date.present? && date < listing_date # before the pair traded
Type guard
def price_gap?(err)
err.is_a?(Provider::BinancePublic::InvalidSecurityPriceError) && err.message.start_with?("No price found")
end Try / catch
begin price = provider.fetch_security_price(symbol: sym, exchange_operating_mic: mic, date: date) rescue Provider::BinancePublic::InvalidSecurityPriceError price = last_known_close_before(sym, date) # fall back to nearest earlier close end
Prevention
- Clamp backfill start dates to the pair's Binance listing date.
- Reject future dates before calling fetch_security_price.
- Treat single-day gaps as data availability, not failure — fall back to the nearest earlier close.
- Rescue per-date so one gap does not abort a range import.
When it happens
Trigger: Requesting a date before the pair was listed on Binance (e.g. a 2019 price for a 2021 coin); requesting a future date; a UTC day on which the pair had no kline data (extremely illiquid/delisted books); date boundary mismatches where the caller's timezone shifts the requested day outside available klines.
Common situations: Backfills that start from a portfolio creation date rather than the coin's listing date; securities whose created_at predates the actual listing; timezone handling passing local dates that resolve to empty UTC windows; retrying recently added coins whose history starts later than the account.
Related errors
- Unauthorized
- API error: #{response.code}
- Unsupported Binance ticker: #{symbol}
- Could not sign in with that passkey. Please try again or use
- External assistant returned an empty response.
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/a7fff9c5764eaa31.
Report an issue: GitHub.