puppetlabs/puppet · error · ArgumentError
Attempt to redefine method %{method} with block
Error message
Attempt to redefine method %{method} with block What it means
newvalue(:name, :method => :sym, &block) optionally defines an instance method :sym on the property class, implemented by the given block; without a block :sym is aliased to call_provider. Puppet refuses to overwrite an already-defined instance method with a block (ArgumentError 'Attempt to redefine method') because silent replacement would hide bugs. Puppet::Property::Ensure itself defines :create and :destroy this way, so those names are classic collisions.
Source
Thrown at lib/puppet/property.rb:172
# to use?
# @option options [Symbol] :invalidate_refreshes Indicates a change on this property should invalidate and
# remove any scheduled refreshes (from notify or subscribe) targeted at the same resource. For example, if
# a change in this property takes into account any changes that a scheduled refresh would have performed,
# then the scheduled refresh would be deleted.
# @option options [Object] any Any other option is treated as a call to a setter having the given
# option name (e.g. `:required_features` calls `required_features=` with the option's value as an
# argument).
#
# @dsl type
# @api public
def self.newvalue(name, options = {}, &block)
value = value_collection.newvalue(name, options, &block)
unless value.method.nil?
method = value.method.to_sym
if value.block
if instance_methods(false).include?(method)
raise ArgumentError, _("Attempt to redefine method %{method} with block") % { method: method }
end
define_method(method, &value.block)
else
# Let the method be an alias for calling the providers setter unless we already have this method
alias_method(method, :call_provider) unless method_defined?(method)
end
end
value
end
# Calls the provider setter method for this property with the given value as argument.
# @return [Object] what the provider returns when calling a setter for this property's name
# @raise [Puppet::Error] when the provider can not handle this property.
# @see #set
# @api private
#
def call_provider(value)View on GitHub (pinned to e227c27540)
Solutions
- Pick a method name that is not already defined (e.g. :make_present instead of :create).
- Drop the :method option so the value aliases to call_provider, and implement the behavior provider-side instead.
- Drop the block and define the method yourself (define_method) where you control collisions explicitly.
Example fix
# before (custom type) newvalue(:present, :method => :create) do provider.create # ArgumentError: 'create' already defined by Puppet::Property::Ensure end # after newvalue(:present, :method => :make_present) do provider.create end
Defensive patterns
Strategy: validation
Validate before calling
method_sym = :make_present
raise ArgumentError, "method :#{method_sym} already defined" if instance_methods(false).include?(method_sym)
newvalue(:present, :method => method_sym) { provider.create } Type guard
def free_value_method?(klass, sym) !klass.instance_methods(false).include?(sym) && !klass.method_defined?(sym) end
Prevention
- Avoid :method names already used by core properties (:create, :destroy from Puppet::Property::Ensure).
- Register each value once; check the property class for existing methods before wiring blocks.
- Search the whole hierarchy (method_defined?) before defining methods through newvalue.
When it happens
Trigger: A property declares newvalue(:present, :method => :create) { ... } while :create already exists - inherited from Property::Ensure or defined earlier in the same class; the same value is registered twice, the second time with :method pointing at a method the first registration created.
Common situations: Custom ensure-like properties copying the ensure idiom; module upgrades that add methods colliding with existing newvalue methods; inheriting from core property classes.
Related errors
- Supported values for Property#array_matching are 'first' and
- Unable to connect to the server at %{uri}. Detail: %{detail}
- Could not convert change '%{name}' to string: %{detail}
- Provider %{provider} must have features '%{needed_feature}'
- Could not convert change %{name} to string: %{detail}
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/7673e179d37eeb79.
Report an issue: GitHub.