puppetlabs/puppet · error · Puppet::Util::Windows::Error

environment variable name must not be nil or empty

Error message

environment variable name must not be nil or empty

What it means

Guard clause in Process.set_environment_variable (lib/puppet/util/windows/process.rb:328): it raises before any Win32 call when the variable name is nil or empty. A pure caller-contract error — the environment is untouched, and the fix is always in the calling code, not the system.

Source

Thrown at lib/puppet/util/windows/process.rb:328

                     # reject any string containing the Unicode replacement character
                     if env_str.include?("\uFFFD")
                       Puppet.warning(_("Discarding environment variable %{string} which contains invalid bytes") % { string: env_str })
                       true
                     end
                   end
                   .map { |env_pair| env_pair.split('=', 2) }
    pairs.to_h
  ensure
    if env_ptr && !env_ptr.null?
      if FreeEnvironmentStringsW(env_ptr) == FFI::WIN32_FALSE
        Puppet.debug "FreeEnvironmentStringsW memory leak"
      end
    end
  end
  module_function :get_environment_strings

  def set_environment_variable(name, val)
    raise Puppet::Util::Windows::Error(_('environment variable name must not be nil or empty')) if !name || name.empty?

    FFI::MemoryPointer.from_string_to_wide_string(name) do |name_ptr|
      if val.nil?
        if SetEnvironmentVariableW(name_ptr, FFI::MemoryPointer::NULL) == FFI::WIN32_FALSE
          raise Puppet::Util::Windows::Error, _("Failed to remove environment variable: %{name}") % { name: name }
        end
      else
        FFI::MemoryPointer.from_string_to_wide_string(val) do |val_ptr|
          if SetEnvironmentVariableW(name_ptr, val_ptr) == FFI::WIN32_FALSE
            raise Puppet::Util::Windows::Error, _("Failed to set environment variable: %{name}") % { name: name }
          end
        end
      end
    end
  end
  module_function :set_environment_variable

  def get_system_default_ui_language

View on GitHub (pinned to e227c27540)

Solutions

  1. Fix the caller: guarantee a non-empty String name before the call and fail fast with context.
  2. Validate required config keys at load time rather than at use time.
  3. Log the backtrace when it fires — the failure is deterministic and points straight at the bad call site.

Example fix

# before — env_key is nil when the config omits it
Process.set_environment_variable(env_key, value)

# after — fail fast with context
raise ArgumentError, 'environment variable name required' if env_key.to_s.strip.empty?
Process.set_environment_variable(env_key, value)
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'env var name must be a non-empty String' unless name.is_a?(String) && !name.empty?
Process.set_environment_variable(name, value)

Type guard

valid_env_name = ->(n) { n.is_a?(String) && !n.empty? && !n.include?('=') }
raise ArgumentError, "bad env var name #{name.inspect}" unless valid_env_name.call(name)

Prevention

When it happens

Trigger: Calling set_environment_variable(nil, value) or set_environment_variable('', value); names computed from hash or config lookups that returned nil or blank strings.

Common situations: Optional configuration feeding environment blocks where a key is silently missing; string interpolation of an unset variable into the name; data-driven provisioning that assumes a key exists.

Related errors


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