puppetlabs/puppet · error · ArgumentError

A block must be given to 'in_tmp_environment'

Error message

A block must be given to 'in_tmp_environment'

What it means

Puppet::Pal.in_tmp_environment requires a block: the whole PAL API is block-scoped, and the temporary environment (created from env_name + modulepath) exists only inside the block. Calling without a block raises ArgumentError.

Source

Thrown at lib/puppet/pal/pal_impl.rb:241

  # @param modulepath [Array<String>] an array of directory paths containing Puppet modules, may be empty, defaults to empty array
  # @param settings_hash [Hash] a hash of settings - currently not used for anything, defaults to empty hash
  # @param facts [Hash] optional map of fact name to fact value - if not given will initialize the facts (which is a slow operation)
  # @param variables [Hash] optional map of fully qualified variable name to value
  # @return [Object] returns what the given block returns
  # @yieldparam [Puppet::Pal] context, a context that responds to Puppet::Pal methods
  #
  def self.in_tmp_environment(env_name,
                              modulepath:    [],
                              settings_hash: {},
                              facts:         nil,
                              variables:     {},
                              &block)
    assert_non_empty_string(env_name, _("temporary environment name"))
    # TRANSLATORS: do not translate variable name string in these assertions
    assert_optionally_empty_array(modulepath, 'modulepath')

    unless block_given?
      raise ArgumentError, _("A block must be given to 'in_tmp_environment'") # TRANSLATORS 'in_tmp_environment' is a name, do not translate
    end

    env = Puppet::Node::Environment.create(env_name, modulepath)

    in_environment_context(
      Puppet::Environments::Static.new(env), # The tmp env is the only known env
      env, facts, variables, &block
    )
  end

  # Defines the context in which to perform puppet operations (evaluation, etc)
  # The code to evaluate in this context is given in a block.
  #
  # The name of an environment (env_name) is always given. The location of that environment on disk
  # is then either constructed by:
  # * searching a given envpath where name is a child of a directory on that path, or
  # * it is the directory given in env_dir (which must exist).
  #

View on GitHub (pinned to e227c27540)

Solutions

  1. Pass a do...end or { } block to in_tmp_environment
  2. In wrappers, accept &block and forward it explicitly to PAL
  3. Verify with respond_to?(:block_given?) style checks in your wrapper before delegating

Example fix

# before
Puppet::Pal.in_tmp_environment('demo', modulepath: [mod])

# after
Puppet::Pal.in_tmp_environment('demo', modulepath: [mod]) do |pal|
  # use pal
end
Defensive patterns

Strategy: validation

Validate before calling

raise ArgumentError, 'block required' unless block_given?
Puppet::Pal.in_tmp_environment(name, modulepath: mp, &block)

Prevention

When it happens

Trigger: Puppet::Pal.in_tmp_environment('demo', modulepath: [m]) with no do...end block; or a wrapper that received &block as nil (caller forgot to forward it).

Common situations: Copy-paste from docs dropping the block; passing a method reference/lambda incorrectly; wrapper methods that forget to accept and forward &block.

Related errors


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