puppetlabs/puppet · error · ArgumentError
A block must be given to 'in_environment'
Error message
A block must be given to 'in_environment'
What it means
Puppet::Pal.in_environment requires a block for the same reason as the other PAL entry points: the environment context (resolved from env_dir or envpath) is established only for the block's duration. Missing block raises ArgumentError.
Source
Thrown at lib/puppet/pal/pal_impl.rb:295
def self.in_environment(env_name,
modulepath: nil,
pre_modulepath: [],
post_modulepath: [],
settings_hash: {},
env_dir: nil,
envpath: nil,
facts: nil,
variables: {},
&block)
# TRANSLATORS terms in the assertions below are names of terms in code
assert_non_empty_string(env_name, 'env_name')
assert_optionally_empty_array(modulepath, 'modulepath', true)
assert_optionally_empty_array(pre_modulepath, 'pre_modulepath', false)
assert_optionally_empty_array(post_modulepath, 'post_modulepath', false)
assert_mutually_exclusive(env_dir, envpath, 'env_dir', 'envpath')
unless block_given?
raise ArgumentError, _("A block must be given to 'in_environment'") # TRANSLATORS 'in_environment' is a name, do not translate
end
if env_dir
unless Puppet::FileSystem.exist?(env_dir)
raise ArgumentError, _("The environment directory '%{env_dir}' does not exist") % { env_dir: env_dir }
end
# a nil modulepath for env_dir means it should use its ./modules directory
mid_modulepath = modulepath.nil? ? [Puppet::FileSystem.expand_path(File.join(env_dir, 'modules'))] : modulepath
env = Puppet::Node::Environment.create(env_name, pre_modulepath + mid_modulepath + post_modulepath)
environments = Puppet::Environments::StaticDirectory.new(env_name, env_dir, env) # The env being used is the only one...
else
assert_non_empty_string(envpath, 'envpath')
# The environment is resolved against the envpath. This is setup without a basemodulepath
# The modulepath defaults to the 'modulepath' in the found env when "Directories" is used
#View on GitHub (pinned to e227c27540)
Solutions
- Supply the block that receives the pal compiler context
- Forward &block through every wrapper layer
- Fail fast in your wrapper with a clearer message using block_given?
Example fix
# before
Puppet::Pal.in_environment('prod', env_dir: dir)
# after
Puppet::Pal.in_environment('prod', env_dir: dir) do |pal|
# compile / evaluate
end Defensive patterns
Strategy: validation
Validate before calling
raise ArgumentError, 'block required' unless block_given? Puppet::Pal.in_environment(name, env_dir: dir, &block)
Prevention
- Treat all Puppet::Pal entry points as block-scoped by contract
- Cover PAL wrappers with a smoke test that always passes a block
When it happens
Trigger: Puppet::Pal.in_environment('production', envpath: path) without a block; delegating wrappers that lose the block.
Common situations: Refactoring PAL calls into helper methods and dropping the &block parameter; scripting examples run partially.
Related errors
- A block must be given to 'in_tmp_environment'
- Given data_type value is not a data type, got '%{type}'
- Given variables must be a hash, got %{type}
- Puppet #{Puppet.version} requires Ruby #{Puppet::OLDEST_RECO
- Invalid entry at %{error_location}: '%{file_text}'
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/707a9b575fbb1a36.
Report an issue: GitHub.