we-promise/sure · warning · Provider::Tiingo::InvalidSecurityPriceError
No prices found for security #{symbol} on date #{date}
Error message
No prices found for security #{symbol} on date #{date} What it means
fetch_security_price narrows to a single day by calling fetch_security_prices(symbol:, start_date: date, end_date: date) and raising InvalidSecurityPriceError when the returned data array is empty. An empty array means Tiingo's daily-prices endpoint accepted the request (no API error was raised) but has no candle rows for that symbol on that date. The most common legitimate cause is a non-trading day; it can also mean the symbol has no end-of-day data (unsupported asset class) or was listed after the date.
Source
Thrown at app/models/provider/tiingo.rb:163
SecurityInfo.new(
symbol: parsed["ticker"] || symbol,
name: parsed["name"],
links: nil,
logo_url: nil,
description: parsed["description"],
kind: nil,
exchange_operating_mic: resolved_mic
)
end
end
def fetch_security_price(symbol:, exchange_operating_mic: nil, date:)
with_provider_response do
historical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date, end_date: date)
raise historical_data.error if historical_data.error.present?
raise InvalidSecurityPriceError, "No prices found for security #{symbol} on date #{date}" if historical_data.data.blank?
historical_data.data.first
end
end
def fetch_security_prices(symbol:, exchange_operating_mic: nil, start_date:, end_date:)
with_provider_response do
throttle_request
track_symbol(symbol)
response = client.get("#{base_url}/tiingo/daily/#{CGI.escape(symbol)}/prices") do |req|
req.params["startDate"] = start_date.to_s
req.params["endDate"] = end_date.to_s
end
parsed = JSON.parse(response.body)
check_api_error!(parsed)
View on GitHub (pinned to e69894adb9)
Solutions
- Validate the date is an exchange trading day before calling, or walk back to the previous trading day
- Confirm the symbol actually returns data: fetch_security_prices over a wider range and inspect which dates exist
- If the symbol is not an equity EOD series (forex/crypto/fund), route it to the provider/endpoint that supports it instead of /tiingo/daily
Example fix
# before price = provider.fetch_security_price(symbol: symbol, date: date) # after trading_day = TradeDate.previous_on_or_before(date, exchange_mic: exchange_operating_mic) price = provider.fetch_security_price(symbol: symbol, exchange_operating_mic: exchange_operating_mic, date: trading_day)
Defensive patterns
Strategy: fallback
Validate before calling
# Check the calendar before asking for a price date = TradingCalendar.previous_trading_day(date) unless TradingCalendar.trading_day?(date)
Try / catch
begin price = provider.fetch_security_price(symbol: sym, date: date) rescue Provider::Tiingo::InvalidSecurityPriceError price = nil # caller falls back to last known price end
Prevention
- Use ranged fetch_security_prices once and pick the wanted date client-side instead of exact-date calls
- Cache last-known prices so a missing single day degrades gracefully
When it happens
Trigger: Calling fetch_security_price(symbol: 'AAPL', date: Date.new(2026, 8, 22)) where that date is a Saturday/Sunday or market holiday; requesting a date before the security's IPO; requesting a forex/crypto symbol on the /tiingo/daily/ equities endpoint which only covers EOD equity data.
Common situations: Manual valuation flows letting users pick arbitrary calendar dates; job that prices securities 'as of today' running on weekends/holidays; portfolios with delisted tickers whose history was trimmed; symbols from other exchanges Tiingo daily doesn't cover.
Related errors
- No prices found for security #{symbol} on date #{date}
- No T-Invest price for #{symbol} on #{date}
- API error: #{error_message}
- Could not sign in with that passkey. Please try again or use
- providers.rentcast.errors.no_valuation
AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21).
Data as JSON: /api/errors/47754b802b65145b.
Report an issue: GitHub.