{"record":{"id":"2ae8619e53fedb01","repo":"puppetlabs/puppet","slug":"illegal-timezone-timezone","errorCode":null,"errorMessage":"Illegal timezone '%{timezone}'","messagePattern":"Illegal timezone '%(.+?)'","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/pops/time/timestamp.rb","lineNumber":42,"sourceCode":"        sprintf('-%2.2d:%2.2d', offset / 60, offset % 60)\n      else\n        sprintf('+%2.2d:%2.2d', offset / 60, offset % 60)\n      end\n    end\n  end\n\n  # Returns the zone offset from utc for the given `timezone`\n  # @param [String] timezone the timezone to get the offset for\n  # @return [Integer] the timezone offset, in seconds\n  #\n  # @api private\n  def self.utc_offset(timezone)\n    if CURRENT_TIMEZONE.casecmp(timezone) == 0\n      ::Time.now.utc_offset\n    else\n      hash = DateTime._strptime(timezone, '%z')\n      offset = hash.nil? ? nil : hash[:offset]\n      raise ArgumentError, _(\"Illegal timezone '%{timezone}'\") % { timezone: timezone } if offset.nil?\n\n      offset\n    end\n  end\n\n  # Formats a ruby Time object using the given timezone\n  def self.format_time(format, time, timezone)\n    unless timezone.nil? || timezone.empty?\n      time = time.localtime(convert_timezone(timezone))\n    end\n    time.strftime(format)\n  end\n\n  def self.now\n    from_time(::Time.now)\n  end\n\n  def self.from_time(t)","sourceCodeStart":24,"sourceCodeEnd":60,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/pops/time/timestamp.rb#L24-L60","documentation":"Timestamp.utc_offset resolves a timezone argument either as the keyword 'current' (uses the Ruby process's local zone) or via DateTime._strptime(timezone, '%z'), which understands numeric offsets like '+02:00', '-0600', and 'Z'. Named zones such as 'PST', 'UTC' (only case-insensitive 'current' is special-cased) or 'America/New_York' do not parse, and ArgumentError 'Illegal timezone' is raised. There is no zoneinfo database lookup here.","triggerScenarios":"Timestamp#format('%F %T %z', 'PST'), Timestamp#format(fmt, 'America/New_York'), Timestamp.parse(str, fmt, 'UTC') - all raise; only 'current', '+05:00', '-0800', 'Z'-style strings work. Reached via convert_timezone, which format_time calls whenever timezone is non-empty.","commonSituations":"Passing IANA zone names from module data into Timestamp#format; assuming 'UTC' is accepted because 'current' is; migrating from Time#in_time_zone('...') APIs; converting reports for humans in named zones.","solutions":["Use a numeric UTC offset string instead of a zone name: '+01:00', '-0500', or the literal 'current'","For 'UTC' pass '+00:00'","Resolve named zones yourself before calling: require 'time'; offset = TZInfo::Timezone.get(name).period_for_utc(Time.now).utc_offset then format with '+HH:MM' built from it","In the Puppet DSL, Timestamp(str, fmt, timezone) has the same constraint - fix the data, not the call"],"exampleFix":"// before\nstamp.format('%F %T %z', 'America/New_York')   # raise\n\n after\nstamp.format('%F %T %z', '-05:00')   # fixed offset; adjust for DST yourself\n# or resolve dynamically:\n# require 'tzinfo'; o = TZInfo::Timezone.get('America/New_York').utc_now_and_offset","handlingStrategy":"validation","validationCode":"def legal_puppet_timezone?(tz)\n  return true if tz.nil? || tz.empty? || tz.casecmp('current') == 0\n  h = DateTime._strptime(tz, '%z')\n  !h.nil? && !h[:offset].nil?\nend\nraise ConfigError, \"zone #{tz} not supported\" unless legal_puppet_timezone?(tz)","typeGuard":"def numeric_zone_or_current?(tz)\n  tz.casecmp('current') == 0 || tz.match?(/\\A[+-]\\d\\d:?\\d\\d\\z/) || tz == 'Z'\nend","tryCatchPattern":"begin\n  stamp.format(fmt, tz)\nrescue ArgumentError => e\n  raise ConfigError, \"timezone #{tz.inspect} rejected - use 'current' or '+HH:MM'\"\nend","preventionTips":["Only 'current' and numeric offsets ('+02:00', '-0800') are legal; named IANA zones are not","Resolve named zones to offsets with TZInfo before calling Timestamp APIs","Validate timezone strings at the config boundary, not per format call"],"tags":["puppet","timestamp","timezone","argument-error","formatting"],"backgroundTag":"invalid-timezone","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}