{"record":{"id":"0d7a617e8c33fc5f","repo":"puppetlabs/puppet","slug":"could-not-convert-change-name-to-string-de","errorCode":null,"errorMessage":"Could not convert change '%{name}' to string: %{detail}","messagePattern":"Could not convert change '%(.+?)' to string: %(.+?)","errorType":"exception","errorClass":"Puppet::DevError","httpStatus":null,"severity":"error","filePath":"lib/puppet/property.rb","lineNumber":218,"sourceCode":"  # Formats a message for a property change from the given `current_value` to the given `newvalue`.\n  # @return [String] a message describing the property change.\n  # @note If called with equal values, this is reported as a change.\n  # @raise [Puppet::DevError] if there were issues formatting the message\n  #\n  def change_to_s(current_value, newvalue)\n    if current_value == :absent\n      \"defined '#{name}' as #{should_to_s(newvalue)}\"\n    elsif newvalue == :absent or newvalue == [:absent]\n      \"undefined '#{name}' from #{is_to_s(current_value)}\"\n    else\n      \"#{name} changed #{is_to_s(current_value)} to #{should_to_s(newvalue)}\"\n    end\n  rescue Puppet::Error\n    raise\n  rescue => detail\n    message = _(\"Could not convert change '%{name}' to string: %{detail}\") % { name: name, detail: detail }\n    Puppet.log_exception(detail, message)\n    raise Puppet::DevError, message, detail.backtrace\n  end\n\n  # Produces the name of the event to use to describe a change of this property's value.\n  # The produced event name is either the event name configured for this property, or a generic\n  # event based on the name of the property with suffix `_changed`, or if the property is\n  # `:ensure`, the name of the resource type and one of the suffixes `_created`, `_removed`, or `_changed`.\n  # @return [String] the name of the event that describes the change\n  #\n  def event_name\n    value = should\n\n    event_name = self.class.value_option(value, :event) and return event_name\n\n    name == :ensure or return (name.to_s + \"_changed\").to_sym\n\n    (resource.type.to_s + case value\n                          when :present; \"_created\"\n                          when :absent;  \"_removed\"","sourceCodeStart":200,"sourceCodeEnd":236,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/property.rb#L200-L236","documentation":"When a property changes, Puppet renders the log/report message via change_to_s, which calls is_to_s and should_to_s on the current and desired values. If those helpers raise, the rescue logs the cause (Puppet.log_exception) and re-raises it as Puppet::DevError including the property name and the original detail; genuine Puppet::Error exceptions pass through unchanged. The message you see is therefore a wrapper - the real defect is whatever the detail reports.","triggerScenarios":"A custom property whose munge, should or should_to_s raises for a specific value; calling change_to_s during report generation when the resource has no provider; values that fail interpolation inside the message helpers.","commonSituations":"Third-party properties with fragile munge blocks; tooling that formats change messages outside a normal transaction; values of an unexpected class reaching message rendering.","solutions":["Read the detail in the message (and the logged original exception) - it names the real failure; fix that munge/should logic.","Make is_to_s/should_to_s defensive: coerce values with to_s/inspect instead of assuming structure.","If you rescue inside those helpers, re-raise Puppet::Error subclasses so they are not double-wrapped."],"exampleFix":"# before (custom property)\ndef should_to_s(v)\n  \"#{v[:name]}=#{v[:value]}\"   # NoMethodError when v is not a Hash -> DevError wrapper\nend\n\n# after\ndef should_to_s(v)\n  v.is_a?(Hash) ? \"#{v[:name]}=#{v[:value]}\" : v.inspect\nend","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"msg = begin\n  property.change_to_s(is_value, should_value)\nrescue Puppet::DevError\n  \"#{property.name} changed #{is_value.inspect} to #{should_value.inspect}\"   # fallback text\nend","preventionTips":["Keep munge/is_to_s/should_to_s total: never assume value shape, use inspect fallbacks.","Unit-test message rendering (call change_to_s directly in property specs) so regressions surface in CI.","Fix the 'detail' exception, not the wrapper: the DevError is only a symptom."],"tags":["puppet","property","logging","message-formatting","custom-type"],"backgroundTag":"to-string-conversion-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}