fluent/fluentd · error · ArgumentError
Template for parser must be a Class, callable object or regu
Error message
Template for parser must be a Class, callable object or regular expression object
What it means
Raised as ArgumentError by the legacy v0.12 registration helper Fluent::Compat::TextParser.register_template(type, template, time_format=nil). Accepted shapes are: a parser Class, any object responding to #call, or a Regexp (wrapped into a RegexpParser together with the optional time_format). Anything else - a parser instance, a String, a Hash of options - is rejected.
Source
Thrown at lib/fluent/compat/parser.rb:91
def parse(text, &block)
if block
@parser.parse(text, &block)
else
@parser.parse(text) { |time, record|
return time, record
}
end
end
def self.register_template(type, template, time_format=nil)
# TODO: warn when deprecated to use Plugin.register_parser directly
if template.is_a?(Class) || template.respond_to?(:call)
Fluent::Plugin.register_parser(type, template)
elsif template.is_a?(Regexp)
Fluent::Plugin.register_parser(type, Proc.new { RegexpParser.new(template, {'time_format' => time_format}) })
else
raise ArgumentError, "Template for parser must be a Class, callable object or regular expression object"
end
end
def self.lookup(format)
# TODO: warn when deprecated to use Plugin.new_parser or RegexpParser.new directly
if format.nil?
raise ConfigError, "'format' parameter is required"
end
if format[0] == ?/ && format[format.length-1] == ?/
# regexp
begin
regexp = Regexp.new(format[1..-2])
if regexp.named_captures.empty?
raise "No named captures"
end
rescue
raise ConfigError, "Invalid regexp '#{format[1..-2]}': #{$!}"View on GitHub (pinned to dd45c6e18d)
Solutions
- Pass the parser class, a Proc, or a Regexp: register_template('apache', /.../, '%d/%b/%Y:%H:%M:%S %z')
- For factory-style registration pass a callable that returns parser instances
- Migrate to the v1 API: Fluent::Plugin.register_parser('my_parser', MyParser)
Example fix
# before
Fluent::Compat::TextParser.register_template('my_parser', MyParser.new)
# after
Fluent::Compat::TextParser.register_template('my_parser', MyParser)
Fluent::Compat::TextParser.register_template('apache', /\A(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \[(?<time>[^\]]*)\]/, '%d/%b/%Y:%H:%M:%S %z') Defensive patterns
Strategy: type-guard
Validate before calling
raise ArgumentError, 'template must be a Class, callable, or Regexp' unless template.is_a?(Class) || template.is_a?(Regexp) || template.respond_to?(:call) Fluent::Compat::TextParser.register_template(type, template, time_format)
Type guard
def parser_template?(t) t.is_a?(Class) || t.is_a?(Regexp) || t.respond_to?(:call) end
Try / catch
begin
Fluent::Compat::TextParser.register_template(type, template)
rescue ArgumentError => e
raise unless e.message.include?('must be a Class, callable object or regular expression')
Fluent::Compat::TextParser.register_template(type, template.class)
end Prevention
- Register parser classes or Regexps, never instances or option hashes
- Pair every Regexp template with an explicit time_format for reliable timestamp parsing
- Prefer the v1 Fluent::Plugin.register_parser API in new code
When it happens
Trigger: TextParser.register_template('my_parser', MyParser.new) (instance instead of class); passing an options Hash or format String; an object that lacks #call.
Common situations: Porting v0.12 plugin registration code; copy-pasting registration calls between parsers of different API generations; switching from Regexp-based to class-based parsers mid-migration.
Related errors
- Template for formatter must be a Class or callable object
- 'format' parameter is required
- both of utc and localtime are specified, use only one of the
- this plugin '#{self.class}' cannot handle arguments for <buf
- this plugin '#{self.class}' allows <buffer tag> only
AI-assisted analysis of fluent/fluentd@dd45c6e18d (2026-08-21).
Data as JSON: /api/errors/b9b87f7da266ff18.
Report an issue: GitHub.