puppetlabs/puppet · error · Puppet::DevError
Could not convert change %{name} to string: %{detail}
Error message
Could not convert change %{name} to string: %{detail} What it means
Property::Ensure#change_to_s formats 'created', 'removed' or '<name> changed <is> to <should>' for the ensure property. If is_to_s or should_to_s raise while formatting, the error is re-raised as Puppet::DevError with the property name and the underlying detail - the same pattern as Property#change_to_s, but without logging the cause first. Custom ensure enumerations (mounted, purged, latest...) are the usual source.
Source
Thrown at lib/puppet/property/ensure.rb:65
def self.inherited(sub)
# Add in the two properties that everyone will have.
sub.class_eval do
end
end
def change_to_s(currentvalue, newvalue)
if currentvalue == :absent || currentvalue.nil?
_("created")
elsif newvalue == :absent
_("removed")
else
_('%{name} changed %{is} to %{should}') % { name: name, is: is_to_s(currentvalue), should: should_to_s(newvalue) }
end
rescue Puppet::Error
raise
rescue => detail
raise Puppet::DevError, _("Could not convert change %{name} to string: %{detail}") % { name: name, detail: detail }, detail.backtrace
end
# Retrieves the _is_ value for the ensure property.
# The existence of the resource is checked by first consulting the provider (if it responds to
# `:exists`), and secondly the resource. A a value of `:present` or `:absent` is returned
# depending on if the managed entity exists or not.
#
# @return [Symbol] a value of `:present` or `:absent` depending on if it exists or not
# @raise [Puppet::DevError] if neither the provider nor the resource responds to `:exists`
#
def retrieve
# XXX This is a problem -- whether the object exists or not often
# depends on the results of other properties, yet we're the first property
# to get checked, which means that those other properties do not have
# @is values set. This seems to be the source of quite a few bugs,
# although they're mostly logging bugs, not functional ones.
prov = @resource.provider
if prov && prov.respond_to?(:exists?)View on GitHub (pinned to e227c27540)
Solutions
- Fix the helper named in the detail (munge, is_to_s or should_to_s) so it handles the failing value.
- Coerce defensively: fall back to inspect for values of unknown shape.
- Re-raise Puppet::Error subclasses from helpers so they are not wrapped.
Example fix
# before (custom type ensure)
def should_to_s(v)
v.split('=').last # NoMethodError for symbols -> DevError wrapper
end
# after
def should_to_s(v)
v.respond_to?(:split) ? v.split('=').last.to_s : v.inspect
end Defensive patterns
Strategy: try-catch
Try / catch
msg = begin
ensure_prop.change_to_s(is_value, should_value)
rescue Puppet::DevError
"ensure #{is_value.inspect} -> #{should_value.inspect}" # fallback text
end Prevention
- Cover every custom ensure value in munge/is_to_s/should_to_s; test message rendering directly.
- Use inspect fallbacks for values of unknown shape.
- Treat the detail as the real error; the DevError is a wrapper around it.
When it happens
Trigger: A custom type's ensure property supports values whose munge or *_to_s helper raises; reporting tooling calls change_to_s with values that never occur during normal syncing; should_to_s dereferences provider state while no provider is present.
Common situations: Custom ensure values with sloppy munges; report parsers or tools that render change messages for arbitrary catalogs.
Related errors
- Could not convert change '%{name}' to string: %{detail}
- No ability to determine if %{name} exists
- Unable to connect to the server at %{uri}. Detail: %{detail}
- Supported values for Property#array_matching are 'first' and
- Attempt to redefine method %{method} with block
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/30ece2c403b8cd93.
Report an issue: GitHub.