{"record":{"id":"597cf421d1fc07d5","repo":"puppetlabs/puppet","slug":"group-names-must-be-provided-not-gid-numbers","errorCode":null,"errorMessage":"Group names must be provided, not GID numbers.","messagePattern":"Group names must be provided, not GID numbers\\.","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/puppet/type/user.rb","lineNumber":347,"sourceCode":"          value\n        end\n      end\n\n      validate do |value|\n        if value.to_s !~ /^-?\\d+$/\n          raise ArgumentError, \"Password warning days must be provided as a number.\"\n        end\n      end\n    end\n\n    newproperty(:groups, :parent => Puppet::Property::List) do\n      desc \"The groups to which the user belongs.  The primary group should\n        not be listed, and groups should be identified by name rather than by\n        GID.  Multiple groups should be specified as an array.\"\n\n      validate do |value|\n        if value =~ /^\\d+$/\n          raise ArgumentError, _(\"Group names must be provided, not GID numbers.\")\n        end\n        raise ArgumentError, _(\"Group names must be provided as an array, not a comma-separated list.\") if value.include?(\",\")\n        raise ArgumentError, _(\"Group names must not be empty. If you want to specify \\\"no groups\\\" pass an empty array\") if value.empty?\n      end\n\n      def change_to_s(currentvalue, newvalue)\n        newvalue = newvalue.split(\",\") if newvalue != :absent\n\n        if provider.respond_to?(:groups_to_s)\n          # for Windows ADSI\n          # de-dupe the \"newvalue\" when the sync event message is generated,\n          # due to final retrieve called after the resource has been modified\n          newvalue = provider.groups_to_s(newvalue).split(',').uniq\n        end\n\n        super(currentvalue, newvalue)\n      end\n","sourceCodeStart":329,"sourceCodeEnd":365,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/type/user.rb#L329-L365","documentation":"Raised by the validate block of the `groups` property (a Puppet::Property::List) on the `user` type. Each group entry must be a name; the check `/^\\d+$/` rejects any member that is purely digits, i.e. a GID. Puppet resolves supplementary groups by name only, because the target system's GID numbering is not assumed to match the manifest's.","triggerScenarios":"`user { 'alice': groups => ['1001'] }` or `groups => '1001'`; converting /etc/group entries directly into manifest data; group names that really are numeric strings are also rejected because they cannot be distinguished from GIDs.","commonSituations":"Porting legacy /etc/passwd-/etc/group-based setup scripts into Puppet; CMDB exports that store numeric group IDs; creating users whose group names are the company employee number.","solutions":["Replace numeric entries with the group's name: `groups => ['developers']`","If the group itself must exist with that GID, manage it separately via `group { 'developers': gid => 1001 }` and reference the name","For genuinely numeric group names on the target OS, quote is not enough — use a non-numeric name or manage membership outside this property"],"exampleFix":"# before\nuser { 'alice':\n  ensure => present,\n  groups => ['1001', '1002'],\n}\n\n# after\ngroup { 'developers': ensure => present, gid => 1001 }\ngroup { 'qa':        ensure => present, gid => 1002 }\nuser { 'alice':\n  ensure => present,\n  groups => ['developers', 'qa'],\n}","handlingStrategy":"validation","validationCode":"# Before building the resource, assert no group entry is all digits\nbad = groups.select { |g| g.to_s.match?(/\\A\\d+\\z/) }\nraise ArgumentError, \"groups must be names, not GIDs: #{bad.join(', ')}\" unless bad.empty?","typeGuard":"def group_names?(list)\n  list.is_a?(Array) && list.all? { |g| g.is_a?(String) && !g.match?(/\\A\\d+\\z/) && !g.empty? && !g.include?(',') }\nend","tryCatchPattern":null,"preventionTips":["Store group lists in Hiera as arrays of names","Add a lint/CI check that rejects all-digit group entries in user data","Manage the groups themselves with the group type (with explicit gid) and reference them by name"],"tags":["puppet","user-resource","groups","gid","argument-validation"],"backgroundTag":"numeric-id-instead-of-name","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}