puppetlabs/puppet · error · ArgumentError
data must be a string, not %{class_name}
Error message
data must be a string, not %{class_name} What it means
ArgumentError from Puppet::Util::Windows::EventLog#report_event: the :data option must be a String because this wrapper logs exactly one wide string via ReportEventW (num_strings is hard-coded to 1, raw data is NULL). No to_s coercion happens, so nil, Integer, or structured objects are rejected before the FFI call.
Source
Thrown at lib/puppet/util/windows/eventlog.rb:62
def close
DeregisterEventSource(@eventlog_handle)
ensure
@eventlog_handle = nil
end
# Report an event to this instance's event log handle. Accepts a string to
# report (:data => <string>) and event type (:event_type => Integer) and id
# (:event_id => Integer) as returned by #to_native. The additional arguments to
# ReportEventW seen in this method aren't exposed - though ReportEventW
# technically can accept multiple strings as well as raw binary data to log,
# we accept a single string from Puppet::Util::Log
#
# @param args [Hash{Symbol=>Object}] options to the associated log event
# @return [void]
# @api public
def report_event(args = {})
unless args[:data].is_a?(String)
raise ArgumentError, _("data must be a string, not %{class_name}") % { class_name: args[:data].class }
end
from_string_to_wide_string(args[:data]) do |message_ptr|
FFI::MemoryPointer.new(:pointer) do |message_array_ptr|
message_array_ptr.write_pointer(message_ptr)
user_sid = FFI::Pointer::NULL
raw_data = FFI::Pointer::NULL
raw_data_size = 0
num_strings = 1
eventlog_category = 0
report_result = ReportEventW(@eventlog_handle, args[:event_type],
eventlog_category, args[:event_id], user_sid,
num_strings, raw_data_size, message_array_ptr, raw_data)
if report_result == WIN32_FALSE
# TRANSLATORS 'Windows' is the operating system and 'ReportEventW' is a API call and should not be translated
raise EventLogError.new(_("ReportEventW failed to report event to Windows eventlog"), FFI.errno)
endView on GitHub (pinned to e227c27540)
Solutions
- Coerce explicitly: report_event(data: message.to_s).
- Fix the upstream pipeline so whatever produces :data guarantees a String.
- Add a spec asserting the data type at the boundary.
Example fix
# before eventlog.report_event(data: log_entry, event_type: 0x0001, event_id: 1) # log_entry not a String # after eventlog.report_event(data: log_entry.to_s, event_type: 0x0001, event_id: 1)
Defensive patterns
Strategy: type-guard
Validate before calling
args[:data] = args[:data].to_s unless args[:data].is_a?(String) eventlog.report_event(args)
Type guard
def string_event_data?(args) args[:data].is_a?(String) end
Try / catch
begin
@eventlog.report_event(args)
rescue ArgumentError => e
warn "dropping non-string event data (#{e.message})"
end Prevention
- Coerce with to_s at the logging boundary.
- Type-check structured payloads before forwarding to the Windows event log.
- Unit-test log sinks with nil and non-string inputs.
When it happens
Trigger: report_event(data: nil), report_event(data: 42), or forwarding a Puppet::Util::Log / hash object as :data — i.e. any caller assuming automatic string conversion.
Common situations: Custom Windows eventlog forwarding hooked into Puppet::Util::Log where the payload is structured; refactors that change what feeds :data from pre-formatted strings to objects.
Related errors
- RegisterEventSourceW failed to open Windows eventlog
- ReportEventW failed to report event to Windows eventlog
- Invalid log level %{level}
- puppet.tasks/unparseable-metadata
- Cannot determine basic system flavour
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/da626221b838f2b7.
Report an issue: GitHub.