we-promise/sure · error · Provider::AlphaVantage::InvalidSecurityPriceError

No prices found for security #{symbol} on date #{date}

Error message

No prices found for security #{symbol} on date #{date}

What it means

Provider::AlphaVantage#fetch_security_price raises InvalidSecurityPriceError when the date-ranged TIME_SERIES_DAILY query returns no rows for the requested symbol/date. Free-tier 'compact' output covers only ~100 trading days (~140 calendar days), so older dates return nothing; weekends/holidays and delisted symbols also yield empty data.

Source

Thrown at app/models/provider/alpha_vantage.rb:168

      SecurityInfo.new(
        symbol: parsed["Symbol"] || symbol,
        name: name,
        links: parsed["OfficialSite"].presence,
        logo_url: nil,
        description: parsed["Description"].presence,
        kind: parsed["AssetType"]&.downcase,
        exchange_operating_mic: exchange_operating_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
      av_symbol = to_av_symbol(symbol, exchange_operating_mic)

      throttle_request
      response = client.get("#{base_url}/query") do |req|
        req.params["function"] = "TIME_SERIES_DAILY"
        req.params["symbol"] = av_symbol
        req.params["outputsize"] = "compact"
      end

      parsed = JSON.parse(response.body)
      check_api_error!(parsed)

View on GitHub (pinned to e69894adb9)

Solutions

  1. Request a recent trading day, or fall back to the last available price within an acceptable window.
  2. For history older than ~140 days, use the full/paid tier or a different provider.
  3. Check that the date is a trading day (skip Sat/Sun and the exchange's holidays).
  4. Rescue InvalidSecurityPriceError and degrade gracefully (e.g. mark value as unavailable instead of crashing a sync).

Example fix

# before
price = provider.fetch_security_price(symbol: symbol, date: date)

# after
begin
  price = provider.fetch_security_price(symbol: symbol, date: date)
rescue Provider::AlphaVantage::InvalidSecurityPriceError
  price = nil # fall back to last known price or skip
end
Defensive patterns

Strategy: fallback

Validate before calling

date >= 140.days.ago.to_date && date.on_weekday? # free-tier compact window heuristic

Try / catch

begin
  provider.fetch_security_price(symbol: s, date: d)
rescue Provider::AlphaVantage::InvalidSecurityPriceError
  prices = provider.fetch_security_prices(symbol: s, start_date: d - 7, end_date: d).data
  prices.last # fall back to the nearest earlier trading day
end

Prevention

When it happens

Trigger: fetch_security_price with a date older than ~140 days; a weekend/holiday date with no trading row; a symbol AV has no series for; date outside the returned window after filtering.

Common situations: Backfilling historical prices on the free tier; asking for the most recent date when markets were closed; invalid ticker.

Related errors


AI-assisted analysis of we-promise/sure@e69894adb9 (2026-08-21). Data as JSON: /api/errors/52e728ff75e9c006. Report an issue: GitHub.