puppetlabs/puppet · error · ArgumentError

Invalid log level %{level}

Error message

Invalid log level %{level}

What it means

Puppet::Util::Windows::Eventlog.to_native maps a Puppet log level symbol to a [Windows event type, event ID] pair so Puppet messages can be written to the Windows Event Log. It accepts exactly eight levels (:debug, :info, :notice, :warning, :err, :alert, :emerg, :crit); anything else raises ArgumentError. The raise is a pure input-validation failure, not a Windows API failure.

Source

Thrown at lib/puppet/util/windows/eventlog.rb:102

  class << self
    # Feels more natural to do Puppet::Util::Window::EventLog.open("MyApplication")
    alias :open :new

    # Query event identifier info for a given log level
    # @param level [Symbol] an event log level
    # @return [Array] Win API Event ID, Puppet Event ID
    # @api public
    def to_native(level)
      case level
      when :debug, :info, :notice
        [EVENTLOG_INFORMATION_TYPE, 0x01]
      when :warning
        [EVENTLOG_WARNING_TYPE, 0x02]
      when :err, :alert, :emerg, :crit
        [EVENTLOG_ERROR_TYPE, 0x03]
      else
        raise ArgumentError, _("Invalid log level %{level}") % { level: level }
      end
    end
  end

  private

  # For the purposes of allowing this class to be standalone, the following are
  # duplicate definitions from elsewhere in Puppet:

  # If we're loaded via Puppet we should keep the previous behavior of raising
  # Puppet::Util::Windows::Error on errors. If we aren't, at least concatenate
  # the error code to the exception message to pass this information on to the
  # user
  if defined?(Puppet::Util::Windows::Error)
    EventLogError = Puppet::Util::Windows::Error
  else
    class EventLogError < RuntimeError
      def initialize(msg, code)

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass one of the eight supported symbols: :debug, :info, :notice, :warning, :err, :alert, :emerg, :crit
  2. Symbolize strings from config before calling: level.to_sym
  3. Map custom/unknown levels to the nearest supported one (e.g. :verbose -> :debug, :fatal -> :emerg)
  4. Rescue ArgumentError at the call site and downgrade to :notice as a safe default

Example fix

// before
Puppet::Util::Windows::Eventlog.to_native('warning')   # String -> ArgumentError
Puppet::Util::Windows::Eventlog.to_native(:verbose)     # custom level -> ArgumentError

// after
level = level.to_sym if level.is_a?(String)
native = Puppet::Util::Windows::Eventlog.to_native(level) rescue Puppet::Util::Windows::Eventlog.to_native(:notice)
Defensive patterns

Strategy: validation

Validate before calling

VALID_EVENTLOG_LEVELS = %i[debug info notice warning err alert emerg crit].freeze
level = level.to_sym if level.is_a?(String)
raise ArgumentError, "unsupported log level #{level}" unless VALID_EVENTLOG_LEVELS.include?(level)
native = Puppet::Util::Windows::Eventlog.to_native(level)

Type guard

def eventlog_level?(value)
  normalized = value.is_a?(String) ? value.to_sym : value
  %i[debug info notice warning err alert emerg crit].include?(normalized)
end

Try / catch

begin
  event_type, event_id = Puppet::Util::Windows::Eventlog.to_native(level)
rescue ArgumentError
  event_type, event_id = Puppet::Util::Windows::Eventlog.to_native(:notice)
end

Prevention

When it happens

Trigger: Calling to_native with a String ('warning' instead of :warning), nil, or a level outside the eight supported symbols, e.g. a custom log level like :verbose or :audit registered by a module or sent by puppetserver. It also fires when forwarding log levels read from YAML/JSON config verbatim without symbolizing.

Common situations: Custom log levels added by site modules or newer Puppet versions that this helper was never taught; log levels arriving as strings over HTTP/report handlers; test fixtures passing capitalized level names (:Warning, :ERROR).

Related errors


AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21). Data as JSON: /api/errors/1b159d1b8199ff36. Report an issue: GitHub.