{"record":{"id":"b9b87f7da266ff18","repo":"fluent/fluentd","slug":"template-for-parser-must-be-a-class-callable-obje","errorCode":null,"errorMessage":"Template for parser must be a Class, callable object or regular expression object","messagePattern":"Template for parser must be a Class, callable object or regular expression object","errorType":"exception","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"lib/fluent/compat/parser.rb","lineNumber":91,"sourceCode":"\n      def parse(text, &block)\n        if block\n          @parser.parse(text, &block)\n        else\n          @parser.parse(text) { |time, record|\n            return time, record\n          }\n        end\n      end\n\n      def self.register_template(type, template, time_format=nil)\n        # TODO: warn when deprecated to use Plugin.register_parser directly\n        if template.is_a?(Class) || template.respond_to?(:call)\n          Fluent::Plugin.register_parser(type, template)\n        elsif template.is_a?(Regexp)\n          Fluent::Plugin.register_parser(type, Proc.new { RegexpParser.new(template, {'time_format' => time_format}) })\n        else\n          raise ArgumentError, \"Template for parser must be a Class, callable object or regular expression object\"\n        end\n      end\n\n      def self.lookup(format)\n        # TODO: warn when deprecated to use Plugin.new_parser or RegexpParser.new directly\n        if format.nil?\n          raise ConfigError, \"'format' parameter is required\"\n        end\n\n        if format[0] == ?/ && format[format.length-1] == ?/\n          # regexp\n          begin\n            regexp = Regexp.new(format[1..-2])\n            if regexp.named_captures.empty?\n              raise \"No named captures\"\n            end\n          rescue\n            raise ConfigError, \"Invalid regexp '#{format[1..-2]}': #{$!}\"","sourceCodeStart":73,"sourceCodeEnd":109,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/compat/parser.rb#L73-L109","documentation":"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.","triggerScenarios":"TextParser.register_template('my_parser', MyParser.new) (instance instead of class); passing an options Hash or format String; an object that lacks #call.","commonSituations":"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.","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)"],"exampleFix":"# before\nFluent::Compat::TextParser.register_template('my_parser', MyParser.new)\n\n# after\nFluent::Compat::TextParser.register_template('my_parser', MyParser)\nFluent::Compat::TextParser.register_template('apache', /\\A(?<host>[^ ]*) [^ ]* (?<user>[^ ]*) \\[(?<time>[^\\]]*)\\]/, '%d/%b/%Y:%H:%M:%S %z')","handlingStrategy":"type-guard","validationCode":"raise ArgumentError, 'template must be a Class, callable, or Regexp' unless template.is_a?(Class) || template.is_a?(Regexp) || template.respond_to?(:call)\nFluent::Compat::TextParser.register_template(type, template, time_format)","typeGuard":"def parser_template?(t)\n  t.is_a?(Class) || t.is_a?(Regexp) || t.respond_to?(:call)\nend","tryCatchPattern":"begin\n  Fluent::Compat::TextParser.register_template(type, template)\nrescue ArgumentError => e\n  raise unless e.message.include?('must be a Class, callable object or regular expression')\n  Fluent::Compat::TextParser.register_template(type, template.class)\nend","preventionTips":["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"],"tags":["fluentd","parser","plugin-registration","v012-compat"],"backgroundTag":"invalid-plugin-registration","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}