puppetlabs/puppet · error · ArgumentError

PP syntax checker: the syntax identifier must be a String…

Error message

PP syntax checker: the syntax identifier must be a String, e.g. pp

What it means

Despite the message text ('must be a String, e.g. pp'), this ArgumentError fires unless syntax is exactly the String 'pp'. The guard is `unless syntax == 'pp'`, so a Symbol :pp, 'PP', 'pp ', or any other valid String like 'ruby' all raise. The checker only handles Puppet Language source, so the identifier must match its registry key 'pp' exactly.

Solutions

  1. Pass the exact literal 'pp' (lowercase String)
  2. Normalize before dispatch: syntax.to_s.downcase.strip
  3. Route by the checker registry key (Puppet.lookup(:plugins)[Puppet::Plugins::SyntaxCheckers::SYNTAX_CHECKERS_KEY]) instead of guessing a checker per identifier

Example fix

# before
checker.check(text, :pp, acceptor, pos) # => ArgumentError

# after
checker.check(text, 'pp', acceptor, pos)
Defensive patterns

Strategy: validation

Validate before calling

syntax = syntax.to_s.downcase.strip if syntax.respond_to?(:to_s)
raise ArgumentError, "unsupported syntax #{syntax.inspect}; PP checker accepts 'pp' only" unless syntax == 'pp'

Prevention

When it happens

Trigger: Calling the PP checker with :pp (Symbol), 'PP', or dispatching a checker by mime-style identifier and routing 'epp'/'ruby' content to the PP checker. Also hit when a syntax tag is built dynamically (string interpolation with trailing whitespace or newlines).

Common situations: Code that normalizes syntax tags with .upcase or .to_sym, generic checker-dispatch frameworks that try each registered checker in turn, or heredoc tags with invisible whitespace copied from documentation.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at lib/puppet/syntax_checkers/pp.rb:19

# frozen_string_literal: true

# A syntax checker for JSON.
# @api public
require_relative '../../puppet/syntax_checkers'
class Puppet::SyntaxCheckers::PP < Puppet::Plugins::SyntaxCheckers::SyntaxChecker
  # Checks the text for Puppet Language 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, _("PP syntax checker: the text to check must be a String.") unless text.is_a?(String)
    raise ArgumentError, _("PP syntax checker: the syntax identifier must be a String, e.g. pp") unless syntax == 'pp'
    raise ArgumentError, _("PP syntax checker: invalid Acceptor, got: '%{klass}'.") % { klass: acceptor.class.name } unless acceptor.is_a?(Puppet::Pops::Validation::Acceptor)

    begin
      Puppet::Pops::Parser::EvaluatingParser.singleton.parse_string(text)
    rescue => e
      # Cap the message to 100 chars and replace newlines
      msg = _("PP 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_PP) { msg }
      acceptor.accept(Puppet::Pops::Validation::Diagnostic.new(:error, issue, source_pos.file, source_pos, {}))
    end
  end
end

View on GitHub (pinned to e227c27540)