{"record":{"id":"f8d40c2b977e3736","repo":"puppetlabs/puppet","slug":"byte-array-for-lookup-account-sid-must-not-be-nil","errorCode":null,"errorMessage":"Byte array for lookup_account_sid must not be nil and must be at least 1 byte long","messagePattern":"Byte array for lookup_account_sid must not be nil and must be at least 1 byte long","errorType":"validation","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/principal.rb","lineNumber":100,"sourceCode":"                      system_name,\n                      sid_ptr.read_bytes(sid_length_ptr.read_dword).unpack('C*')\n                    )\n                  end\n                end\n              end\n            end\n          end\n        end\n      ensure\n        system_name_ptr.free if system_name_ptr != FFI::Pointer::NULL\n      end\n    end\n\n    def self.lookup_account_sid(system_name = nil, sid_bytes)\n      system_name_ptr = FFI::Pointer::NULL\n      if sid_bytes.nil? || (!sid_bytes.is_a? Array) || (sid_bytes.length == 0)\n        # TRANSLATORS `lookup_account_sid` is a variable name and should not be translated\n        raise Puppet::Util::Windows::Error, _('Byte array for lookup_account_sid must not be nil and must be at least 1 byte long')\n      end\n\n      begin\n        if system_name\n          system_name_wide = Puppet::Util::Windows::String.wide_string(system_name)\n          system_name_ptr = FFI::MemoryPointer.from_wide_string(system_name_wide)\n        end\n\n        FFI::MemoryPointer.new(:byte, sid_bytes.length) do |sid_ptr|\n          FFI::MemoryPointer.new(:dword, 1) do |name_length_ptr|\n            FFI::MemoryPointer.new(:dword, 1) do |domain_length_ptr|\n              FFI::MemoryPointer.new(:uint32, 1) do |name_use_enum_ptr|\n                sid_ptr.write_array_of_uchar(sid_bytes)\n\n                if Puppet::Util::Windows::SID.IsValidSid(sid_ptr) == FFI::WIN32_FALSE\n                  raise Puppet::Util::Windows::Error.new(_('Byte array for lookup_account_sid is invalid: %{sid_bytes}') % { sid_bytes: sid_bytes }, ERROR_INVALID_PARAMETER)\n                end\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/principal.rb#L82-L118","documentation":"Guard clause at the top of Principal.lookup_account_sid (lib/puppet/util/windows/principal.rb:100). Before any Win32 call it rejects sid_bytes that is nil, not an Array, or empty, raising Puppet::Util::Windows::Error. It is a caller-contract failure: SIDs must be passed as a non-empty Ruby Array of byte-sized integers — exactly what lookup_account_name produces via read_bytes(...).unpack('C*').","triggerScenarios":"Calling lookup_account_sid with a SID string like 'S-1-5-18' instead of a byte array; passing [] because an upstream read/unpack produced nothing; passing a String of raw bytes or an FFI pointer instead of an Array.","commonSituations":"Custom providers hand-rolling SID handling instead of using SID.octet_string_to_principal; byte arrays built from Ruby strings without unpack('C*'); nil propagated from a failed earlier lookup (e.g. name_to_principal returning nil).","solutions":["Obtain bytes from a resolved Principal: Puppet::Util::Windows::SID.name_to_principal(name).sid_bytes is always a valid byte Array.","Use SID.octet_string_to_principal(bytes), which validates the shape for you.","If converting from a SID string, use SID.string_to_sid_ptr and read_array_of_uchar(SID.get_length_sid(ptr)).","Fix the caller to pass Array bytes (integers 0-255) and fail fast on nil upstream instead of propagating it."],"exampleFix":"# before — string passed instead of a byte array\nPrincipal.lookup_account_sid('S-1-5-18')\n\n# after — bytes obtained from a resolved Principal\nprincipal = Puppet::Util::Windows::SID.name_to_principal('SYSTEM')\nbytes = principal.sid_bytes # non-empty Array of bytes\nPrincipal.lookup_account_sid(bytes)","handlingStrategy":"validation","validationCode":"raise ArgumentError, 'sid_bytes must be a non-empty Array' unless sid_bytes.is_a?(Array) && !sid_bytes.empty?\nPrincipal.lookup_account_sid(sid_bytes)","typeGuard":"sid_bytes_valid = ->(v) { v.is_a?(Array) && !v.empty? && v.all? { |b| b.is_a?(Integer) && b.between?(0, 255) } }\nraise ArgumentError, 'invalid SID byte array' unless sid_bytes_valid.call(sid_bytes)","tryCatchPattern":null,"preventionTips":["Treat sid_bytes as a typed contract: non-empty Array of 0..255 integers","Use SID.octet_string_to_principal / Principal#sid_bytes rather than hand-building arrays","Fail fast on nil results from earlier lookups instead of passing them on"],"tags":["windows","validation","argument-check","sid","puppet"],"backgroundTag":"invalid-argument-validation","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}