puppetlabs/puppet · error · Puppet::Error

#{detail} on node #{node_name}

Error message

#{detail} on node #{node_name}

What it means

This is Puppet::Parser::ScriptCompiler#compile's catch-all rescue, not a distinct failure itself. When compiling a script (the ScriptCompiler path used for one-shot script execution with an environment), any exception that is NOT a Puppet::ParseErrorWithIssue gets re-wrapped as Puppet::Error with " on node <node_name>" appended and logged via Puppet.log_exception. The original exception is preserved as the cause with its backtrace, so the real fault is always the wrapped `detail`.

Source

Thrown at lib/puppet/parser/script_compiler.rb:60

    # TRANSLATORS, "For running script" is not user facing
    Puppet.override(@context_overrides, "For running script") do
      # TRANSLATORS "main" is a function name and should not be translated
      result = Puppet::Util::Profiler.profile(_("Script: Evaluated main"), [:script, :evaluate_main]) { evaluate_main }
      if block_given?
        yield self
      else
        result
      end
    end
  rescue Puppet::ParseErrorWithIssue => detail
    detail.node = node_name
    Puppet.log_exception(detail)
    raise
  rescue => detail
    message = "#{detail} on node #{node_name}"
    Puppet.log_exception(detail, message)
    raise Puppet::Error, message, detail.backtrace
  end

  # Constructs the overrides for the context
  def context_overrides
    {
      :current_environment => environment,
      :global_scope => @topscope, # 4x placeholder for new global scope
      :loaders => @loaders, # 4x loaders
      :rich_data => true,
    }
  end

  # Create a script compiler for the given environment where errors are logged as coming
  # from the given node_name
  #
  def initialize(environment, node_name, for_agent = false)
    @environment = environment
    @node_name = node_name

View on GitHub (pinned to e227c27540)

Solutions

  1. Read the full exception chain: the wrapped original is available as the Puppet::Error's cause (or via `--trace` / Puppet.log_exception output) — fix that underlying error, not the wrapper.
  2. Run with `--trace` (or Puppet[:trace] = true) to get the original backtrace showing which function/expression raised.
  3. If the failure is intermittent (network, Hiera backend), make the failing call conditional/retried at the script level before re-running compile.
  4. In Ruby embedding (pal), rescue Puppet::Error and inspect `error.cause` to branch on the real failure class.

Example fix

# before (embedding pal/script compiler)
begin
  compiler.compile
rescue Puppet::Error => e
  puts e.message        # "RuntimeError ... on node web1" — real cause hidden
end

# after
begin
  compiler.compile
rescue Puppet::Error => e
  root = e.cause || e
  puts "#{root.class}: #{root.message}"
  puts root.backtrace
end
Defensive patterns

Strategy: try-catch

Validate before calling

# Validate the script cheaply before compiling:
Puppet::Pops::Parser::EvaluatingParser.new.validate_string(script_code)
# (catches parse-level issues; runtime failures still need rescue below)

Try / catch

begin
  script_compiler.compile
rescue Puppet::ParseErrorWithIssue => e
  # already has file/line — handle directly
  report(e)
rescue Puppet::Error => e
  root = e.cause || e        # unwrap the "on node X" wrapper
  report(root)
end

Prevention

When it happens

Trigger: ScriptCompiler#compile (or the Puppet::Pal / `puppet apply`-style script entry points that use it) evaluating a script whose code raises: a failing function call, a Ruby error inside a custom function, an assert_type failure, a failed lookup — anything outside ParseErrorWithIssue. The rescue fires per-compile, tags the node name, and re-raises Puppet::Error wrapping the original.

Common situations: Running manifests/scripts through pal/script compilation where a custom function raises a RuntimeError; environment or loader problems surfacing as plain Ruby exceptions; users confused because the visible message is the generic '<original message> on node mynode' and the actionable detail is nested inside.

Related errors


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