puppetlabs/puppet · error · ArgumentError

EPP syntax checker: invalid Acceptor, got: '%{klass}'.

Error message

EPP syntax checker: invalid Acceptor, got: '%{klass}'.

What it means

Puppet's pluggable syntax-checker API validates EPP template text. The check method in lib/puppet/syntax_checkers/epp.rb requires the third argument to be an instance of Puppet::Pops::Validation::Acceptor, the diagnostic collector that gathers errors and warnings. Passing any other object, even one that duck-types #accept, raises ArgumentError before any parsing happens. In normal operation (heredoc/template validation via Puppet::Pops::Evaluator::ExternalSyntaxSupport#assert_external_syntax) the runtime always constructs a real Acceptor, so this error signals direct API misuse.

Source

Thrown at lib/puppet/syntax_checkers/epp.rb:20

# A syntax checker for JSON.
# @api public
require_relative '../../puppet/syntax_checkers'
class Puppet::SyntaxCheckers::EPP < Puppet::Plugins::SyntaxCheckers::SyntaxChecker
  # Checks the text for Puppet Language EPP syntax issues and reports them to the given acceptor.
  #
  # Error messages from the checker are capped at 100 chars from the source text.
  #
  # @param text [String] The text to check
  # @param syntax [String] The syntax identifier in mime style (only accepts 'pp')
  # @param acceptor [#accept] A Diagnostic acceptor
  # @param source_pos [Puppet::Pops::Adapters::SourcePosAdapter] A source pos adapter with location information
  # @api public
  #
  def check(text, syntax, acceptor, source_pos)
    raise ArgumentError, _("EPP syntax checker: the text to check must be a String.") unless text.is_a?(String)
    raise ArgumentError, _("EPP syntax checker: the syntax identifier must be a String, e.g. pp") unless syntax == 'epp'
    raise ArgumentError, _("EPP syntax checker: invalid Acceptor, got: '%{klass}'.") % { klass: acceptor.class.name } unless acceptor.is_a?(Puppet::Pops::Validation::Acceptor)

    begin
      Puppet::Pops::Parser::EvaluatingParser::EvaluatingEppParser.singleton.parse_string(text)
    rescue => e
      # Cap the message to 100 chars and replace newlines
      msg = _("EPP syntax checker: \"%{message}\"") % { message: e.message().slice(0, 500).gsub(/\r?\n/, "\\n") }

      # TODO: improve the pops API to allow simpler diagnostic creation while still maintaining capabilities
      # and the issue code. (In this case especially, where there is only a single error message being issued).
      #
      issue = Puppet::Pops::Issues.issue(:ILLEGAL_EPP) { msg }
      acceptor.accept(Puppet::Pops::Validation::Diagnostic.new(:error, issue, source_pos.file, source_pos, {}))
    end
  end
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Construct the acceptor exactly as the evaluator does: acceptor = Puppet::Pops::Validation::Acceptor.new, pass it to check, then read acceptor.diagnostics
  2. If you need custom reporting, keep the real Acceptor and inspect its diagnostics after the call instead of substituting your own collector class
  3. For a genuinely custom pipeline, wrap rather than replace: call the checker with a real Acceptor and post-process acceptor.diagnostics

Example fix

# before
checker = Puppet::SyntaxCheckers::EPP.new
checker.check(text, 'epp', MyCollector.new, source_pos) # => ArgumentError

# after
checker = Puppet::SyntaxCheckers::EPP.new
acceptor = Puppet::Pops::Validation::Acceptor.new
checker.check(text, 'epp', acceptor, source_pos)
acceptor.diagnostics.each { |d| puts d.message }
Defensive patterns

Strategy: type-guard

Validate before calling

raise ArgumentError, "acceptor must be an Acceptor, got #{acceptor.class}" unless acceptor.is_a?(Puppet::Pops::Validation::Acceptor)

Type guard

def valid_acceptor?(a)
  a.is_a?(Puppet::Pops::Validation::Acceptor)
end

Try / catch

begin
  checker.check(text, 'epp', acceptor, pos)
rescue ArgumentError => e
  raise ConfigError, "EPP checker API misused: #{e.message}"
end

Prevention

When it happens

Trigger: Calling Puppet::SyntaxCheckers::EPP.new.check(text, 'epp', acceptor, source_pos) with a custom collector object, an Array, a Proc, or a test double instead of a Puppet::Pops::Validation::Acceptor. Also hit when a custom checker registered under Puppet::Plugins::SyntaxCheckers::SYNTAX_CHECKERS_KEY forwards its acceptor argument incorrectly.

Common situations: Writing RSpec tests around the checker API, building custom lint/CI tooling that wraps Puppet's EPP validation, or refactoring code that previously passed a hand-rolled acceptor that happened to work against an older Puppet version.

Understand the failure class

Background: Invalid argument type errors: "must be of type string", "expected X, got Y", and ERR_INVALID_ARG_TYPE explained — this error's family across 15 libraries.

Related errors


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