{"record":{"id":"0049ece5b9b36820","repo":"we-promise/sure","slug":"enable-banking-session-is-not-valid-or-has-expired","errorCode":null,"errorMessage":"Enable Banking session is not valid or has expired","messagePattern":"Enable Banking session is not valid or has expired","errorType":"exception","errorClass":"StandardError","httpStatus":null,"severity":"warning","filePath":"app/models/enable_banking_item.rb","lineNumber":197,"sourceCode":"    update!(session_expires_at: parsed)\n  rescue ArgumentError, TypeError, ActiveRecord::ActiveRecordError => e\n    # Best-effort reconciliation: swallow bad timestamps (ArgumentError/TypeError)\n    # as well as validation/locking failures from update! (RecordInvalid,\n    # StaleObjectError) so a sync is never derailed by expiry bookkeeping.\n    Rails.logger.warn \"EnableBankingItem #{id} - Failed to reconcile session expiry: #{e.message}\"\n  end\n\n  def import_latest_enable_banking_data\n    provider = enable_banking_provider\n    unless provider\n      Rails.logger.error \"EnableBankingItem #{id} - Cannot import: Enable Banking provider is not configured\"\n      raise StandardError.new(\"Enable Banking provider is not configured\")\n    end\n\n    unless session_valid?\n      Rails.logger.error \"EnableBankingItem #{id} - Cannot import: Session is not valid\"\n      update!(status: :requires_update)\n      raise StandardError.new(\"Enable Banking session is not valid or has expired\")\n    end\n\n    EnableBankingItem::Importer.new(self, enable_banking_provider: provider).import\n  rescue => e\n    Rails.logger.error \"EnableBankingItem #{id} - Failed to import data: #{e.message}\"\n    raise\n  end\n\n  def process_accounts\n    return [] if enable_banking_accounts.empty?\n\n    results = []\n    enable_banking_accounts.joins(:account).merge(Account.visible).each do |enable_banking_account|\n      begin\n        result = EnableBankingAccount::Processor.new(enable_banking_account).process\n        results << { enable_banking_account_id: enable_banking_account.id, success: true, result: result }\n      rescue => e\n        Rails.logger.error \"EnableBankingItem #{id} - Failed to process account #{enable_banking_account.id}: #{e.message}\"","sourceCodeStart":179,"sourceCodeEnd":215,"githubUrl":"https://github.com/we-promise/sure/blob/e69894adb92547273377398c15f45c979cd9416a/app/models/enable_banking_item.rb#L179-L215","documentation":"ArgumentError raised by validate_date_params! when validated_end_date > Date.current. The provider refuses to ask Yahoo for future quotes; prices for dates that have not closed yet do not exist. Note it compares against Date.current (server timezone), so a UTC 'today' vs app-timezone 'today' mismatch at day boundaries can trip it near midnight.","triggerScenarios":"Calling fetch_security_prices with end_date = Date.tomorrow (e.g., user requests 'next 7 days' of prices); timezone skew: server in UTC late evening while app timezone already rolled to the next day; date pickers that default end_date to end-of-week inclusive of tomorrow.","commonSituations":"Forward-looking valuation requests (projected portfolio value); cron jobs running near UTC midnight computing 'today' differently from the app timezone; imports with exchange timezones ahead of the server.","solutions":["Clamp end_date to Date.current before calling: end_date = [end_date, Date.current].min","Align date computation with the exchange's timezone rather than the server clock","In UIs, disable future dates in the range picker","If 'today' prices are wanted, request end_date = Date.current and accept the last close"],"exampleFix":"# before\nprovider.fetch_security_prices(symbol: s, start_date: start, end_date: user_end_date)\n\n# after\nend_date = [user_end_date.to_date, Date.current].min\nprovider.fetch_security_prices(symbol: s, start_date: start, end_date: end_date)","handlingStrategy":"validation","validationCode":"end_date = [end_date.to_date, Date.current].min # never ask for future quotes","typeGuard":null,"tryCatchPattern":"begin\n  provider.fetch_security_prices(symbol: sym, start_date: s, end_date: e)\nrescue ArgumentError => e\n  raise unless e.message.include?(\"cannot be in the future\")\n  e = Date.current\n  retry\nend","preventionTips":["Clamp end_date to today at the boundary before any provider call","Compute 'today' in the exchange's timezone for near-midnight jobs","Disable future dates in range pickers"],"tags":["yahoo-finance","date-validation","future-date","timezone"],"backgroundTag":"invalid-date-range","analyzedSha":"e69894adb92547273377398c15f45c979cd9416a","analyzedAt":"2026-08-21T18:22:41.165Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}