{"record":{"id":"f42a9ec1d43e5f9b","repo":"we-promise/sure","slug":"invalid-search-response-format-e-message","errorCode":null,"errorMessage":"Invalid search response format: #{e.message}","messagePattern":"Invalid search response format: #(.+?)","errorType":"exception","errorClass":"Provider::YahooFinance::Error","httpStatus":null,"severity":"error","filePath":"app/models/provider/yahoo_finance.rb","lineNumber":229,"sourceCode":"        securities = quotes.filter_map do |quote|\n          mic = map_exchange_mic(quote[\"exchange\"])\n\n          Security.new(\n            symbol: quote[\"symbol\"],\n            name: quote[\"longname\"] || quote[\"shortname\"] || quote[\"symbol\"],\n            logo_url: nil, # Yahoo search doesn't provide logos\n            exchange_operating_mic: mic,\n            country_code: ::Security::EXCHANGES.dig(mic, \"country\") || map_country_code(quote[\"exchDisp\"])\n          )\n        end\n\n        securities = deduplicate_dual_listings(securities) unless exchange_operating_mic.present?\n\n        cache_result(cache_key, securities)\n        securities\n      end\n    rescue JSON::ParserError => e\n      raise Error, \"Invalid search response format: #{e.message}\"\n    end\n  end\n\n  def fetch_security_info(symbol:, exchange_operating_mic:)\n    with_provider_response do\n      symbol = normalize_symbol(symbol, exchange_operating_mic)\n\n      # quoteSummary endpoint requires cookie/crumb authentication\n      throttle_request\n      cookie, crumb = fetch_cookie_and_crumb\n\n      response = authenticated_client(cookie).get(\"#{base_url}/v10/finance/quoteSummary/#{symbol}\") do |req|\n        req.params[\"modules\"] = \"assetProfile,price,quoteType\"\n        req.params[\"crumb\"] = crumb\n      end\n\n      data = JSON.parse(response.body)\n","sourceCodeStart":211,"sourceCodeEnd":247,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/yahoo_finance.rb#L211-L247","documentation":"Provider::YahooFinance::Error raised in search_securities when JSON.parse fails on the /v1/finance/search response. The endpoint answered with a non-JSON body (HTML block page, empty body, or changed content type), so parsing raised JSON::ParserError and got converted to a typed error.","triggerScenarios":"The unauthenticated Yahoo search endpoint returning an HTML captcha/consent page or rate-limit page instead of JSON; an empty 204-style body; response intercepted by a proxy.","commonSituations":"Rapid symbol searches from a datacenter IP tripping Yahoo's bot defenses; Yahoo deploying breaking changes to the unofficial endpoint; intermittent CDN errors.","solutions":["Capture and inspect the raw body when this fires to distinguish HTML blocks from truncation","Throttle searches (the provider paces at 0.5s; keep interactive autocomplete debounced too)","Retry after a delay or fall back to another security-search provider","Cache search results (the provider already caches 5 min) so repeat queries don't re-hit Yahoo"],"exampleFix":"// before\nsecurities = provider.search_securities(params[:q])\n\n// after\nbegin\n  securities = provider.search_securities(params[:q])\nrescue Provider::YahooFinance::Error => e\n  raise unless e.message.start_with?(\"Invalid search response format\")\n  securities = fallback_provider.search_securities(params[:q])\nend","handlingStrategy":"retry","validationCode":"return [] if query.to_s.strip.length < 2","typeGuard":null,"tryCatchPattern":"begin\n  provider.search_securities(query)\nrescue Provider::YahooFinance::Error => e\n  raise unless e.message.start_with?(\"Invalid search response format\")\n  sleep 5\n  retry if (attempts += 1) < 2\n  fallback_provider.search_securities(query)\nend","preventionTips":["Debounce autocomplete inputs (>=300ms) and cache queries","Pace searches — MIN_REQUEST_INTERVAL is 0.5s per instance; share pacing across processes","Keep a secondary search provider for when Yahoo serves block pages"],"tags":["ruby","yahoo-finance","json-parse-error","symbol-search","scraping"],"backgroundTag":"invalid-json-response","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}