puppetlabs/puppet · error · ArgumentError

Both type and title must be given

Error message

Both type and title must be given

What it means

Puppet::Pal::JsonCatalogEncoder#encode_resource requires both the resource type name and the title; if either is nil it raises ArgumentError before touching the catalog. The guard exists because the underlying catalog lookup behaves unpredictably when title is nil.

Source

Thrown at lib/puppet/pal/json_catalog_encoder.rb:56

  # @return String The catalog in Json format using rich data format
  # @api public
  #
  def encode
    possibly_filtered_catalog.to_json(:pretty => pretty)
  end

  # Returns one particular resource as a Json string, or returns nil if resource was not found.
  # @param type [String] the name of the puppet type (case independent)
  # @param title [String] the title of the wanted resource
  # @return [String] the resulting Json text
  # @api public
  #
  def encode_resource(type, title)
    # Ensure that both type and title are given since the underlying API will do mysterious things
    # if 'title' is nil. (Other assertions are made by the catalog when looking up the resource).
    #
    # TRANSLATORS 'type' and 'title' are internal parameter names - do not translate
    raise ArgumentError, _("Both type and title must be given") if type.nil? or title.nil?

    r = possibly_filtered_catalog.resource(type, title)
    return nil if r.nil?

    r.to_data_hash.to_json(:pretty => pretty)
  end

  # Applies a filter for virtual resources and returns filtered catalog
  # or the catalog itself if filtering was not needed.
  # The result is cached.
  # @api private
  # rubocop:disable Naming/MemoizedInstanceVariableName
  def possibly_filtered_catalog
    @filtered ||= (exclude_virtual ? catalog.filter(&:virtual?) : catalog)
  end
  private :possibly_filtered_catalog
  # rubocop:enable Naming/MemoizedInstanceVariableName
end

View on GitHub (pinned to e227c27540)

Solutions

  1. Check both type and title are non-nil before calling encode_resource
  2. Fix the data source: use fetch/default so the values are always present strings
  3. Iterate catalog.resources and encode each instead of looking up by type/title

Example fix

# before
encoder.encode_resource(params['type'], params['tile']) # typo -> nil

# after
type  = params.fetch('type')
title = params.fetch('title')
json  = type && title ? encoder.encode_resource(type, title) : nil
Defensive patterns

Strategy: validation

Validate before calling

return nil unless type.is_a?(String) && !type.empty? && title && !title.to_s.empty?
encoder.encode_resource(type, title)

Type guard

def encodable_ref?(type, title)
  type.is_a?(String) && !type.empty? && title.is_a?(String) && !title.empty?
end

Prevention

When it happens

Trigger: encoder.encode_resource('File', nil), encode_resource(nil, 'conf'), or dynamic lookups like encode_resource(res['type'], res['title']) where a hash key is missing or misspelled and yields nil.

Common situations: Driving catalog-to-JSON export from user-supplied hashes or YAML where fields are optional; key typos (:tile vs :title); iterating filtered resources whose title is empty.

Related errors


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