puppetlabs/puppet · error · NotImplementedError
Call 'all_tags' instead.
Error message
Call 'all_tags' instead.
What it means
TemplateWrapper#tags intentionally raises NotImplementedError. In old Puppet versions ERB templates could call `tags` to get the current scope's tags; that was removed, and the method now exists only to point callers at all_tags, which returns scope.catalog.tags. Because it raises during template rendering, it aborts the catalog compile of whichever template invoked it.
Source
Thrown at lib/puppet/parser/templatewrapper.rb:55
end
private :script_line
# Should return true if a variable is defined, false if it is not
# @api public
def has_variable?(name)
scope.include?(name.to_s)
end
# @return [Array<String>] The list of defined classes
# @api public
def classes
scope.catalog.classes
end
# @return [Array<String>] The tags defined in the current scope
# @api public
def tags
raise NotImplementedError, "Call 'all_tags' instead."
end
# @return [Array<String>] All the defined tags
# @api public
def all_tags
scope.catalog.tags
end
# @api private
def file=(filename)
@__file__ = Puppet::Parser::Files.find_template(filename, scope.compiler.environment)
unless @__file__
raise Puppet::ParseError, _("Could not find template '%{filename}'") % { filename: filename }
end
end
# @api private
def result(string = nil)View on GitHub (pinned to e227c27540)
Solutions
- Replace `tags` with `all_tags` in the template: `<%= all_tags.inspect %>`.
- If you needed per-scope behavior, derive it from scope variables or pass data into the template explicitly instead.
- Lock the module to a Puppet version matching its templates, or patch and upstream a fix to the module.
Example fix
# before (mod/templates/motd.erb)
<% if tags.include?('web') %>Web node<% end %>
# after
<% if all_tags.include?('web') %>Web node<% end %> Defensive patterns
Strategy: validation
Validate before calling
# Grep templates for removed API before upgrade: # rg "<%[^>]*\btags\b" modules/*/templates/ # Anything found must switch to all_tags.
Prevention
- Use all_tags in ERB templates; 'tags' has been gone since early Puppet.
- Add a CI grep/lint step for removed template APIs when upgrading Puppet or vendored modules.
- Prefer EPP templates (Puppet DSL) for new code — they use @all_tags and stay in the supported surface.
When it happens
Trigger: An ERB template containing `<%= tags %>` or `<% tags.each do |t| %>` rendered via `template('mod/name.erb')` or inline_template. The wrapper binds its methods into the template's binding, so the call dispatches to TemplateWrapper#tags and raises immediately.
Common situations: Templates written for Puppet 2.x/early 3.x reused in modern Puppet; copy-pasting old blog examples that gate sections on tags; modules not updated after the tags API change (the NotImplementedError pointer was added to make migration discoverable).
Related errors
- Could not find template '%{filename}'
- Unrecognized value for request 'merge' parameter: '%{merge}'
- Cannot transform a number to a tag
- Template %{file} does not exist
- GetVersionEx failed
AI-assisted analysis of puppetlabs/puppet@e227c27540 (2026-08-21).
Data as JSON: /api/errors/945187b43c1bfc17.
Report an issue: GitHub.