{"record":{"id":"6acb68a0a7ab65f8","repo":"we-promise/sure","slug":"api-error-parsed-error-message","errorCode":null,"errorMessage":"API error: #{parsed[\"Error Message\"]}","messagePattern":"API error: #(.+?)","errorType":"exception","errorClass":"Provider::AlphaVantage::Error","httpStatus":null,"severity":"error","filePath":"app/models/provider/alpha_vantage.rb","lineNumber":337,"sourceCode":"    # Alpha Vantage returns errors as JSON keys rather than HTTP status codes.\n    def check_api_error!(parsed)\n      return unless parsed.is_a?(Hash)\n\n      # Rate limit: Alpha Vantage returns a \"Note\" key when rate-limited\n      if parsed[\"Note\"].present?\n        Rails.logger.warn(\"AlphaVantage rate limit: #{parsed[\"Note\"]}\")\n        raise RateLimitError, parsed[\"Note\"]\n      end\n\n      # General info/limit messages\n      if parsed[\"Information\"].present?\n        Rails.logger.warn(\"AlphaVantage info: #{parsed[\"Information\"]}\")\n        raise RateLimitError, parsed[\"Information\"]\n      end\n\n      # Explicit error messages for invalid parameters\n      if parsed[\"Error Message\"].present?\n        raise Error, \"API error: #{parsed[\"Error Message\"]}\"\n      end\n    end\nend\n","sourceCodeStart":319,"sourceCodeEnd":341,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/alpha_vantage.rb#L319-L341","documentation":"In the same check_api_error!, a present \"Error Message\" key in the response body raises Provider::AlphaVantage::Error with \"API error: <message>\". Alpha Vantage returns \"Error Message\" for invalid API calls: unknown/typo'd symbols, invalid function names, bad interval parameters, or malformed query strings. Unlike the \"Note\"/\"Information\" keys, this is a hard request failure, not a quota condition.","triggerScenarios":"Calling a price/quote endpoint with a nonexistent ticker symbol (e.g. \"BRK.A\" instead of \"BRK-B\"), an invalid interval, a delisted symbol, a wrong FUNCTION parameter, or a malformed query string. Any provider call whose parsed body contains \"Error Message\" triggers it before data extraction.","commonSituations":"User saves a ticker with an exchange-specific suffix Alpha Vantage does not accept; symbol was delisted/renamed; copy-paste whitespace in the symbol; provider switched endpoint naming; wrong API function name after a library update.","solutions":["Verify the symbol returns data on Alpha Vantage's own API demo page (or curl the endpoint with your key) and correct/normalize the symbol (e.g. dashes instead of dots for class shares).","Check the function/interval parameters the provider sends for that call and confirm they are supported for the symbol's market.","Rescue Provider::AlphaVantage::Error in the caller and surface a user-facing 'invalid symbol' message instead of a stack trace.","If the symbol is valid via curl, confirm the app is sending the API key you think it is (not a demo key)."],"exampleFix":"# before\nsync_security(symbol: \"BRK.A\") # => raises \"API error: Invalid API call...\"\n\n# after\nbegin\n  sync_security(symbol: normalized_symbol)\nrescue Provider::AlphaVantage::Error => e\n  Rails.logger.error(\"Alpha Vantage rejected symbol: #{e.message}\")\n  mark_security_as_unsupported # keep sync healthy, flag the row\nend","handlingStrategy":"try-catch","validationCode":"def valid_alpha_vantage_symbol?(symbol)\n  symbol.is_a?(String) && symbol.match?(/\\A[A-Z0-9.\\-]{1,20}\\z/) && !symbol.strip.empty?\nend","typeGuard":null,"tryCatchPattern":"begin\n  provider.fetch(symbol)\nrescue Provider::AlphaVantage::Error => e\n  mark_security_unsupported(symbol, reason: e.message) # flag row, keep sync green\nend","preventionTips":["Normalize symbols before saving (strip whitespace, use dash-form class shares like BRK-B).","Rescue Provider::AlphaVantage::Error separately from RateLimitError so invalid symbols don't trigger backoff logic.","Validate symbol format at the settings/upload boundary, not only at sync time."],"tags":["alpha-vantage","invalid-symbol","bad-request","securities","stock-prices"],"backgroundTag":"invalid-api-request","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}