{"record":{"id":"6019131fd5104891","repo":"puppetlabs/puppet","slug":"klass-does-not-respond-to-intern-multiple-met","errorCode":null,"errorMessage":"#{klass} does not respond to #{intern_multiple_method}; can not intern multiple instances from #{mime}","messagePattern":"#(.+?) does not respond to #(.+?); can not intern multiple instances from #(.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"lib/puppet/network/format.rb","lineNumber":61,"sourceCode":"    end\n\n    raise ArgumentError, _(\"Unsupported option(s) %{options_list}\") % { options_list: @options.keys } unless @options.empty?\n\n    @options = nil\n\n    instance_eval(&block) if block_given?\n  end\n\n  def intern(klass, text)\n    return klass.send(intern_method, text) if klass.respond_to?(intern_method)\n\n    raise NotImplementedError, \"#{klass} does not respond to #{intern_method}; can not intern instances from #{mime}\"\n  end\n\n  def intern_multiple(klass, text)\n    return klass.send(intern_multiple_method, text) if klass.respond_to?(intern_multiple_method)\n\n    raise NotImplementedError, \"#{klass} does not respond to #{intern_multiple_method}; can not intern multiple instances from #{mime}\"\n  end\n\n  def mime=(mime)\n    @mime = mime.to_s.downcase\n  end\n\n  def render(instance)\n    return instance.send(render_method) if instance.respond_to?(render_method)\n\n    raise NotImplementedError, \"#{instance.class} does not respond to #{render_method}; can not render instances to #{mime}\"\n  end\n\n  def render_multiple(instances)\n    # This method implicitly assumes that all instances are of the same type.\n    return instances[0].class.send(render_multiple_method, instances) if instances[0].class.respond_to?(render_multiple_method)\n\n    raise NotImplementedError, _(\"%{klass} does not respond to %{method}; can not render multiple instances to %{mime}\") %\n                               { klass: instances[0].class, method: render_multiple_method, mime: mime }","sourceCodeStart":43,"sourceCodeEnd":79,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/network/format.rb#L43-L79","documentation":"A Puppet::Network::Format binds a mime type to named methods on the classes it can serialize. intern_multiple(klass, text) deserializes many instances at once by calling the format's intern_multiple_method (for json, from_json_multiple) on the class; when the class does not respond to that method, this NotImplementedError is raised — the format exists, but this class never implemented the multiple-instance entry point.","triggerScenarios":"Klass.convert_from_multiple(:json, '[...]') (FormatSupport) or format.intern_multiple(klass, text) where klass lacks the method named by the format's intern_multiple_method — e.g. a custom model defining from_json but not the multiple variant, or a custom format registered without an intern_multiple implementation.","commonSituations":"Custom indirected models (faces, report handlers) that only implement single-object parsing; formats created with Puppet::Network::FormatHandler.create whose method names match nothing on the model; Puppet versions where a model lacks msgpack interning.","solutions":["Define the missing class method on your model — for the json format: def self.from_json_multiple(text) ... end (mirror whatever intern_multiple_method the format names).","Check what the class supports and stay inside it: Klass.supported_formats — only call convert_from_multiple for formats listed there.","If you own the format definition, provide the implementation inline: Puppet::Network::FormatHandler.create(:foo, ...) { intern_multiple { |klass, text| ... } }.","For single payloads call convert_from (intern) instead of the multiple variant."],"exampleFix":"# before\nclass Widget\n  include Puppet::Network::FormatSupport\n  def self.from_json(text) = Widget.new(Puppet::Util::Json.load(text))\nend\nWidget.convert_from_multiple(:json, '[{\"id\":1}]')\n# => NotImplementedError: Widget does not respond to from_json_multiple\n\n# after\nclass Widget\n  def self.from_json(text) = Widget.new(Puppet::Util::Json.load(text))\n  def self.from_json_multiple(text) = Puppet::Util::Json.load(text).map { |h| Widget.new(h) }\nend","handlingStrategy":"type-guard","validationCode":"fmt = Puppet::Network::FormatHandler.format(:json)\nabort 'json format not registered' if fmt.nil?\nabort 'Widget lacks multiple interning' unless Widget.respond_to?(fmt.intern_multiple_method)\nlist = Widget.convert_from_multiple(:json, payload)","typeGuard":"def interns_multiple?(klass, format_name)\n  fmt = Puppet::Network::FormatHandler.format(format_name)\n  !fmt.nil? && klass.respond_to?(fmt.intern_multiple_method)\nend","tryCatchPattern":"begin\n  Widget.convert_from_multiple(:json, payload)\nrescue NotImplementedError => e\n  raise unless e.message.include?('does not respond to')\n  # degrade to per-item interning\n  Puppet::Util::Json.load(payload).map { |h| Widget.convert_from(:json, Puppet::Util::Json.dump(h)) }\nend","preventionTips":["When mixing in FormatSupport, implement the full method set (from_*, from_*_multiple, to_*) for every advertised format.","Route external format choices through supported_formats instead of raw input.","For custom formats, wire intern_multiple to a proc in the format block rather than a method name.","Unit-test multi-instance round-trips, not only single objects."],"tags":["puppet","ruby","serialization","formats","interface"],"backgroundTag":"missing-interface-method","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}