puppetlabs/puppet · error · ArgumentError

Role names must be provided, not numbers

Error message

Role names must be provided, not numbers

What it means

Raised by the validate block of the `roles` property (a Puppet::Property::List with :required_features => :manages_roles) on the `user` type. Roles are RBAC role names, not numeric IDs; any member matching /^\d+$/ is rejected. The property is only usable with providers declaring manages_roles (Solaris user_role_add, Windows ADSI).

Source

Thrown at lib/puppet/type/user.rb:527

    # (see Puppet::Settings#service_user_available?)
    #
    # @return [Boolean] if the user exists on the system
    # @api private
    def exists?
      provider.exists?
    end

    newproperty(:roles, :parent => Puppet::Property::List, :required_features => :manages_roles) do
      desc "The roles the user has.  Multiple roles should be
        specified as an array."

      def membership
        :role_membership
      end

      validate do |value|
        if value =~ /^\d+$/
          raise ArgumentError, _("Role names must be provided, not numbers")
        end
        raise ArgumentError, _("Role names must be provided as an array, not a comma-separated list") if value.include?(",")
      end
    end

    # autorequire the roles that the user has
    autorequire(:user) do
      reqs = []

      roles_property = @parameters[:roles]
      roles = roles_property.should if roles_property
      if roles
        reqs += roles.split(',')
      end

      reqs
    end unless Puppet::Util::Platform.windows?

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass role names: `roles => ['sysadmin']`
  2. Create the roles themselves with the `role` type on Solaris and reference them by name
  3. Fix the data source to export names, not numeric IDs

Example fix

# before
user { 'alice':
  ensure => present,
  roles  => ['10'],
}

# after
role { 'sysadmin': ensure => present }
user { 'alice':
  ensure => present,
  roles  => ['sysadmin'],
}
Defensive patterns

Strategy: validation

Validate before calling

bad = roles.select { |r| r.to_s.match?(/\A\d+\z/) }
raise ArgumentError, "roles must be names: #{bad.inspect}" unless bad.empty?

Type guard

def role_names?(list)
  list.is_a?(Array) && list.all? { |r| r.is_a?(String) && !r.match?(/\A\d+\z/) && !r.include?(',') }
end

Prevention

When it happens

Trigger: `user { 'alice': roles => ['10'] }` or `roles => '10'` on Solaris with the user_role_add provider, or on Windows via ADSI groups-as-roles; RBAC data exported as numeric role IDs from a CMDB.

Common situations: Converting Solaris `usermod -R` scripts or roleadd outputs into manifests; ID-based identity management exports; the property silently not being supported on plain Linux useradd is a separate feature error, this one fires when the value format is numeric.

Related errors


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