{"record":{"id":"9ac942e983e58562","repo":"puppetlabs/puppet","slug":"failed-to-remove-environment-variable-name","errorCode":null,"errorMessage":"Failed to remove environment variable: %{name}","messagePattern":"Failed to remove environment variable: %(.+?)","errorType":"exception","errorClass":"Puppet::Util::Windows::Error","httpStatus":null,"severity":"error","filePath":"lib/puppet/util/windows/process.rb","lineNumber":333,"sourceCode":"                   end\n                   .map { |env_pair| env_pair.split('=', 2) }\n    pairs.to_h\n  ensure\n    if env_ptr && !env_ptr.null?\n      if FreeEnvironmentStringsW(env_ptr) == FFI::WIN32_FALSE\n        Puppet.debug \"FreeEnvironmentStringsW memory leak\"\n      end\n    end\n  end\n  module_function :get_environment_strings\n\n  def set_environment_variable(name, val)\n    raise Puppet::Util::Windows::Error(_('environment variable name must not be nil or empty')) if !name || name.empty?\n\n    FFI::MemoryPointer.from_string_to_wide_string(name) do |name_ptr|\n      if val.nil?\n        if SetEnvironmentVariableW(name_ptr, FFI::MemoryPointer::NULL) == FFI::WIN32_FALSE\n          raise Puppet::Util::Windows::Error, _(\"Failed to remove environment variable: %{name}\") % { name: name }\n        end\n      else\n        FFI::MemoryPointer.from_string_to_wide_string(val) do |val_ptr|\n          if SetEnvironmentVariableW(name_ptr, val_ptr) == FFI::WIN32_FALSE\n            raise Puppet::Util::Windows::Error, _(\"Failed to set environment variable: %{name}\") % { name: name }\n          end\n        end\n      end\n    end\n  end\n  module_function :set_environment_variable\n\n  def get_system_default_ui_language\n    GetSystemDefaultUILanguage()\n  end\n  module_function :get_system_default_ui_language\n\n  # Returns whether or not the OS has the ability to set elevated","sourceCodeStart":315,"sourceCodeEnd":351,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/util/windows/process.rb#L315-L351","documentation":"Raised by set_environment_variable (lib/puppet/util/windows/process.rb:333) when the removal form of the API — SetEnvironmentVariableW(name, NULL) — returns FALSE. Windows answers with ERROR_ENVVAR_NOT_FOUND (203) when the variable is not present; other codes cover malformed names (embedded '=') or an environment the caller does not control. Removal is not idempotent at the Win32 level, so 'ensure absent' style workflows hit this naturally.","triggerScenarios":"Removing a variable that was never set or was already removed earlier in the run (code 203); a name containing '='; unconditional cleanup calls in idempotent provisioning.","commonSituations":"Cleanup or provisioning scripts that remove variables unconditionally; a race with another writer deleting the variable first; hosts with differing environment baselines.","solutions":["Rescue Puppet::Util::Windows::Error and treat e.code == 203 (ERROR_ENVVAR_NOT_FOUND) as success for removal semantics.","Check presence first via Process.get_environment_strings when you need explicit state transitions.","Sanitize the name (no '=', sane length) before calling.","For persistent machine/user variables, manage the registry environment keys and broadcast WM_SETTINGCHANGE instead of this per-process API."],"exampleFix":"# before — raises when the variable is already absent\nProcess.set_environment_variable('MY_VAR', nil)\n\n# after — idempotent removal\nbegin\n  Process.set_environment_variable('MY_VAR', nil)\nrescue Puppet::Util::Windows::Error => e\n  raise unless e.code == 203 # ERROR_ENVVAR_NOT_FOUND — already gone\nend","handlingStrategy":"try-catch","validationCode":"# only attempt removal when present\npresent = Process.get_environment_strings.key?(name)\nProcess.set_environment_variable(name, nil) if present","typeGuard":null,"tryCatchPattern":"begin\n  Process.set_environment_variable(name, nil)\nrescue Puppet::Util::Windows::Error => e\n  raise unless e.code == 203 # ERROR_ENVVAR_NOT_FOUND\n  # already absent — treat as success\nend","preventionTips":["Treat code 203 as success in any 'ensure absent' logic","Check presence with get_environment_strings before conditional workflows","Remember this API only touches the calling process's environment, not the persisted machine/user set"],"tags":["windows","win32-api","environment-variables","idempotency","ffi","puppet"],"backgroundTag":"win32-setenvironmentvariable-failed","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}