{"record":{"id":"3a52b107251d27ab","repo":"fluent/fluentd","slug":"optional-api-parse-io-is-not-implemented","errorCode":null,"errorMessage":"Optional API #parse_io is not implemented","messagePattern":"Optional API #parse_io is not implemented","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"lib/fluent/plugin/parser.rb","lineNumber":174,"sourceCode":"\n      def call(*a, &b)\n        # Keep backward compatibility for existing plugins\n        # TODO: warn when deprecated\n        parse(*a, &b)\n      end\n\n      def implement?(feature)\n        methods_of_plugin = self.class.instance_methods(false)\n        case feature\n        when :parse_io then methods_of_plugin.include?(:parse_io)\n        when :parse_partial_data then methods_of_plugin.include?(:parse_partial_data)\n        else\n          raise ArgumentError, \"Unknown feature for parser plugin: #{feature}\"\n        end\n      end\n\n      def parse_io(io, &block)\n        raise NotImplementedError, \"Optional API #parse_io is not implemented\"\n      end\n\n      def parse_partial_data(data, &block)\n        raise NotImplementedError, \"Optional API #parse_partial_data is not implemented\"\n      end\n\n      def parse_time(record)\n        if @time_key && record.respond_to?(:has_key?) && record.has_key?(@time_key)\n          src = if @keep_time_key\n                  record[@time_key]\n                else\n                  record.delete(@time_key)\n                end\n          @time_parser.parse(src)\n        elsif @estimate_current_event\n          Fluent::EventTime.now\n        else\n          nil","sourceCodeStart":156,"sourceCodeEnd":192,"githubUrl":"https://github.com/fluent/fluentd/blob/dd45c6e18dc7be33b5e5a0f0767bf46307ff5626/lib/fluent/plugin/parser.rb#L156-L192","documentation":"Optional parser API guard (lib/fluent/plugin/parser.rb:174): the base Parser#parse_io raises NotImplementedError unless the concrete parser overrides it (json and msgpack parsers do). parse_io lets a parser stream-parse an IO object instead of a whole string; in_exec/out_exec_filter call it only after implement?(:parse_io) returns true. Hitting the raise means the base implementation was invoked directly, bypassing or defeating that guard.","triggerScenarios":"Calling parser.parse_io(io) on a parser of a type that does not define it (e.g. @type regexp, csv, syslog); a custom parser subclass whose implement? logic was overridden to return true without defining parse_io; aliasing/removing methods so instance_methods(false) includes :parse_io but it delegates to super.","commonSituations":"Custom input plugin authors copying the in_exec dispatch block but hardcoding the parse_io branch; monkey-patched parsers (e.g. by compat shims like parser_compat) that alter the method table; plugins that define parse_io on the class but an ancestor cache or typo makes the base method win.","solutions":["Always gate the call: unless parser.implement?(:parse_io), fall back to parser.parse(io.read).","If your custom parser declares parse_io in its method table, actually define def parse_io(io, &block) instead of aliasing the base.","Do not override implement? manually; let the default instance_methods(false) detection work.","Switch to a parser type that supports IO streaming (@type json or @type msgpack) when streaming parse is required."],"exampleFix":"# before\n@parser.parse_io(io) { |t, r| on_record(t, r) } # raises if not implemented\n# after\nif @parser.implement?(:parse_io)\n  @parser.parse_io(io) { |t, r| on_record(t, r) }\nelse\n  @parser.parse(io.read) { |t, r| on_record(t, r) }\nend","handlingStrategy":"validation","validationCode":"if @parser.implement?(:parse_io)\n  @parser.parse_io(io, &callback)\nelse\n  @parser.parse(io.read, &callback)\nend","typeGuard":"def parse_io_capable?(parser)\n  parser.class.instance_methods(false).include?(:parse_io)\nend","tryCatchPattern":"begin\n  @parser.parse_io(io, &callback)\nrescue NotImplementedError\n  @parser.parse(io.read, &callback)\nend","preventionTips":["Mirror the in_exec/out_exec_filter dispatch pattern with implement? checks.","Prefer @type json or @type msgpack when streaming IO parsing is required.","Never override implement? manually in custom parsers."],"tags":["fluentd","parser-plugin","not-implemented","optional-api","io-streaming"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"dd45c6e18dc7be33b5e5a0f0767bf46307ff5626","analyzedAt":"2026-08-21T16:22:07.332Z","schemaVersion":2},"datasetVersion":"2026-08-21T18:17:14.833Z"}