{"record":{"id":"3a762788f4943d01","repo":"SeleniumHQ/selenium","slug":"invalid-value-for-expiration-date-obj-inspect","errorCode":null,"errorMessage":"invalid value for expiration date: #{obj.inspect}","messagePattern":"invalid value for expiration date: #(.+?)","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"rb/lib/selenium/webdriver/common/manager.rb","lineNumber":130,"sourceCode":"\n      private\n\n      SECONDS_PER_DAY = 86_400.0\n\n      def datetime_at(int)\n        DateTime.civil(1970) + (int / SECONDS_PER_DAY)\n      end\n\n      def seconds_from(obj)\n        case obj\n        when Time\n          obj.to_f\n        when DateTime\n          (obj - DateTime.civil(1970)) * SECONDS_PER_DAY\n        when Numeric\n          obj\n        else\n          raise ArgumentError, \"invalid value for expiration date: #{obj.inspect}\"\n        end\n      end\n\n      def strip_port(str)\n        str.split(':', 2).first\n      end\n\n      def convert_cookie(cookie)\n        {\n          name: cookie['name'],\n          value: cookie['value'],\n          path: cookie['path'],\n          domain: cookie['domain'] && strip_port(cookie['domain']),\n          expires: cookie['expiry'] && datetime_at(cookie['expiry']),\n          same_site: cookie['sameSite'],\n          http_only: cookie['httpOnly'],\n          secure: cookie['secure']\n        }","sourceCodeStart":112,"sourceCodeEnd":148,"githubUrl":"https://github.com/SeleniumHQ/selenium/blob/aa36b38e696a0909e973bdf5e2f9031ffe842c4b/rb/lib/selenium/webdriver/common/manager.rb#L112-L148","documentation":"The private seconds_from helper converts the :expires cookie option into epoch seconds. It only accepts Time, DateTime, or Numeric values. Any other type (e.g. a String or a Date) raises ArgumentError. This value is then used for the cookie's expiry.","triggerScenarios":"Passing expires: '2025-12-31' (a String) to add_cookie. Passing a Date object instead of DateTime/Time. Passing an arbitrary object as :expires.","commonSituations":"Reading an expiry from JSON/config as a String and passing it directly. Using Date.today instead of Time.now/DateTime.now. Expecting the library to parse date strings.","solutions":["Convert date strings to Time before passing: expires: Time.parse('2025-12-31').","Pass epoch seconds directly as a Numeric: expires: 1767225600.","Use DateTime/Time objects (e.g. Time.now + 86400) rather than Date or String."],"exampleFix":"# before\ndriver.manage.add_cookie(name: 'sid', value: 'x', expires: '2025-12-31')\n\n# after\nrequire 'time'\ndriver.manage.add_cookie(name: 'sid', value: 'x', expires: Time.parse('2025-12-31'))","handlingStrategy":"type-guard","validationCode":"expires = case val\n          when Time, DateTime, Numeric then val\n          when String then Time.parse(val)\n          else raise ArgumentError, 'unsupported expires type'\n          end","typeGuard":"def valid_expires?(obj)\n  obj.is_a?(Time) || obj.is_a?(DateTime) || obj.is_a?(Numeric)\nend","tryCatchPattern":"begin\n  driver.manage.add_cookie(name: 'x', value: 'y', expires: val)\nrescue ArgumentError => e\n  raise unless e.message.include?('expiration date')\n  driver.manage.add_cookie(name: 'x', value: 'y', expires: Time.parse(val))\nend","preventionTips":["Parse date strings to Time with require 'time'; Time.parse(str) before passing.","Prefer epoch seconds (Numeric) for portability.","Avoid Date objects; use DateTime or Time instead."],"tags":["ruby","cookies","date","type-error"],"backgroundTag":null,"analyzedSha":"aa36b38e696a0909e973bdf5e2f9031ffe842c4b","analyzedAt":"2026-08-14T02:32:32.244Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}