{"record":{"id":"3b1f4392e0ba5c96","repo":"we-promise/sure","slug":"not-found-3b1f43","errorCode":"not_found","errorMessage":"Resource not found","messagePattern":"Resource not found","errorType":"exception","errorClass":"Error","httpStatus":404,"severity":"error","filePath":"app/models/provider/indexa_capital.rb","lineNumber":208,"sourceCode":"    end\n\n    def handle_response(response)\n      case response.code\n      when 200, 201\n        begin\n          JSON.parse(response.body, symbolize_names: true)\n        rescue JSON::ParserError => e\n          raise Error.new(\"Invalid JSON in response: #{e.message}\", :bad_response)\n        end\n      when 400\n        Rails.logger.error \"IndexaCapital API: Bad request - #{response.body}\"\n        raise Error.new(\"Bad request: #{response.body}\", :bad_request)\n      when 401\n        raise AuthenticationError.new(\"Invalid credentials\", :unauthorized)\n      when 403\n        raise AuthenticationError.new(\"Access forbidden - check your permissions\", :access_forbidden)\n      when 404\n        raise Error.new(\"Resource not found\", :not_found)\n      when 429\n        raise Error.new(\"Rate limit exceeded. Please try again later.\", :rate_limited)\n      when 500..599\n        raise Error.new(\"IndexaCapital server error (#{response.code}). Please try again later.\", :server_error)\n      else\n        Rails.logger.error \"IndexaCapital API: Unexpected response - Code: #{response.code}, Body: #{response.body}\"\n        raise Error.new(\"Unexpected error: #{response.code} - #{response.body}\", :unknown)\n      end\n    end\n\n    # Extract accounts array from /users/me response\n    # API returns: { accounts: [{ account_number: \"ABC12345\", type: \"mutual\", status: \"active\", ... }] }\n    def extract_accounts(user_data)\n      accounts = user_data[:accounts] || []\n      accounts.map do |acct|\n        {\n          account_number: acct[:account_number],\n          name: account_display_name(acct),","sourceCodeStart":190,"sourceCodeEnd":226,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/provider/indexa_capital.rb#L190-L226","documentation":"The API answered HTTP 404 for a well-formed request: the account_number is syntactically valid (sanitize_account_number! passed) but no such resource exists under this credential, or the endpoint itself was removed/moved.","triggerScenarios":"Account closed at Indexa but still in your sync list; a transposed 8-char code (e.g. \"LPYH3CMQ\" vs \"LPYH3MCQ\"); Indexa renamed/removed an endpoint (then every account 404s, not just one); querying fiscal-results for an account type that lacks it entirely.","commonSituations":"Stale account lists after a user closes an Indexa account, OCR/manual entry of account numbers, API version bumps that moved paths.","solutions":["Call list_accounts and diff: accounts missing from the fresh list should be deactivated locally, not retried","If ALL accounts suddenly 404, suspect an endpoint/contract change - check Indexa API docs before touching data","Treat :not_found as a permanent condition for that account: stop syncing it rather than retrying","Verify the exact number character-by-character against the dashboard"],"exampleFix":"# before\nprovider.get_portfolio(account_number: account.account_number)\n\n# after\nfresh = provider.list_accounts.map { |a| a[:account_number] }\nunless fresh.include?(account.account_number)\n  account.update!(sync_disabled: true, disable_reason: \"gone_from_provider\")\n  next\nend\nprovider.get_portfolio(account_number: account.account_number)","handlingStrategy":"validation","validationCode":"fresh_numbers = provider.list_accounts.map { |a| a[:account_number] }\nunless fresh_numbers.include?(account.account_number)\n  account.update!(sync_disabled: true, disable_reason: \"gone_from_provider\")\n  return\nend\nprovider.get_portfolio(account_number: account.account_number)","typeGuard":"def indexa_not_found?(error)\n  error.is_a?(Provider::IndexaCapital::Error) && error.error_type == :not_found\nend","tryCatchPattern":"begin\n  provider.get_account_balance(account_number: num)\nrescue Provider::IndexaCapital::Error => e\n  raise unless e.error_type == :not_found\n  account.update!(sync_disabled: true, disable_reason: \"not_found_at_provider\") # permanent\nend","preventionTips":["Refresh the account list at the start of every sync and diff against stored accounts","Treat :not_found as permanent for that account - disable, don't retry","If EVERY account 404s at once, suspect an endpoint change - check docs before bulk-disabling","Compare stored numbers character-by-character after manual entry"],"tags":["indexa-capital","http-404","not-found","stale-account","resource-missing"],"backgroundTag":"http-404-not-found","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}