{"record":{"id":"724d1e986aaa8c8d","repo":"we-promise/sure","slug":"no-nav-found-for-scheme-symbol-on-or-before-d","errorCode":null,"errorMessage":"No NAV found for scheme #{symbol} on or before #{date}","messagePattern":"No NAV found for scheme #(.+?) on or before #(.+?)","errorType":"exception","errorClass":"Provider::Mfapi::InvalidSecurityPriceError","httpStatus":null,"severity":"error","filePath":"app/models/provider/mfapi.rb","lineNumber":93,"sourceCode":"\n      SecurityInfo.new(\n        symbol: symbol,\n        name: meta[\"scheme_name\"],\n        links: nil,\n        logo_url: nil,\n        description: [ meta[\"fund_house\"], meta[\"scheme_category\"] ].compact.join(\" - \"),\n        kind: \"mutual fund\",\n        exchange_operating_mic: exchange_operating_mic\n      )\n    end\n  end\n\n  def fetch_security_price(symbol:, exchange_operating_mic: nil, date:)\n    with_provider_response do\n      historical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date - 7.days, end_date: date)\n\n      raise historical_data.error if historical_data.error.present?\n      raise InvalidSecurityPriceError, \"No NAV found for scheme #{symbol} on or before #{date}\" if historical_data.data.blank?\n\n      # Find exact date or closest previous\n      historical_data.data.select { |p| p.date <= date }.max_by(&:date) || historical_data.data.first\n    end\n  end\n\n  def fetch_security_prices(symbol:, exchange_operating_mic: nil, start_date:, end_date:)\n    with_provider_response do\n      throttle_request\n      response = client.get(\"#{base_url}/mf/#{CGI.escape(symbol)}\") do |req|\n        req.params[\"startDate\"] = start_date.to_s\n        req.params[\"endDate\"] = end_date.to_s\n      end\n\n      parsed = JSON.parse(response.body)\n      check_api_error!(parsed)\n\n      nav_data = parsed[\"data\"]","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/mfapi.rb#L75-L111","documentation":"Raised by Provider::Mfapi#fetch_security_price (an InvalidSecurityPriceError subclass) when a 7-day lookback window (date - 7.days .. date) of NAV entries comes back with zero usable rows. MFAPI publishes one NAV per Indian business day, so this means the window contained no NAV records at all — not merely that the exact date was missing (the code already falls back to the closest previous date or first record). The upstream fetch must have succeeded (its error is re-raised first), so this is a data-availability failure, not a transport failure.","triggerScenarios":"Requesting a date earlier than the fund's inception (e.g. a 2023 date for a 2025 NFO); querying a scheme code whose data array was returned but every entry was filtered out by filter_map (nav nil, nav <= 0, blank DD-MM-YYYY date); a date range falling entirely in a long NAV-publication gap; wrong schemeCode that MFAPI still answers with an empty data array.","commonSituations":"Backfilling portfolio history for newly launched schemes; user typed an ISIN or name instead of the numeric schemeCode; stale symbol saved before the scheme merged/wound up; requesting today's date before the AMFI NAV for today is published and the previous week's window somehow returns empty.","solutions":["Verify the schemeCode is a real MFAPI scheme: hit https://api.mfapi.in/mf/{schemeCode} directly and confirm the data array is non-empty for your window.","Widen the lookback window (e.g. date - 30.days) so inception gaps and publication holidays still resolve to the nearest prior NAV.","Clamp requested dates to on/after the scheme's first NAV (meta scheme_start_date from the /mf/{code} response) before calling.","Catch InvalidSecurityPriceError at the sync layer and mark the price as missing for that date instead of failing the whole sync."],"exampleFix":"# before\nhistorical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date - 7.days, end_date: date)\n\n# after\nhistorical_data = fetch_security_prices(symbol:, exchange_operating_mic:, start_date: date - 30.days, end_date: date)","handlingStrategy":"try-catch","validationCode":"raise ArgumentError, \"date must be on/after scheme inception\" if date < scheme.inception_date if scheme.respond_to?(:inception_date)","typeGuard":null,"tryCatchPattern":"begin\n  nav = provider.fetch_security_price(symbol: code, date: date)\nrescue Provider::Mfapi::InvalidSecurityPriceError\n  nav = nil # carry forward last known NAV / skip this date\nend","preventionTips":["Query a wider window than the expected NAV publication cadence before concluding no NAV exists.","Store each scheme's first NAV date at sync time and clamp future requests to it.","Treat a numeric schemeCode as mandatory input — resolve names/ISINs via search first."],"tags":["mfapi","mutual-funds","nav","historical-prices","empty-data"],"backgroundTag":"no-historical-price-data","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}