{"record":{"id":"471778c3117994c6","repo":"puppetlabs/puppet","slug":"instance-class-does-not-respond-to-render-met","errorCode":null,"errorMessage":"#{instance.class} does not respond to #{render_method}; can not render instances to #{mime}","messagePattern":"#(.+?) does not respond to #(.+?); can not render instances to #(.+?)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"lib/puppet/network/format.rb","lineNumber":71,"sourceCode":"    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 }\n  end\n\n  def required_methods_present?(klass)\n    [:intern_method, :intern_multiple_method, :render_multiple_method].each do |name|\n      return false unless required_method_present?(name, klass, :class)\n    end\n\n    return false unless required_method_present?(:render_method, klass, :instance)\n\n    true","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/puppetlabs/puppet/blob/e227c27540975c25aa22d533a52424a9d2fc886a/lib/puppet/network/format.rb#L53-L89","documentation":"Format#render(instance) serializes one object by sending the format's render_method (to_json, to_yaml, to_msgpack) to the instance. If the instance's class never defines that method, NotImplementedError is raised. Called through FormatSupport#render it is normally wrapped as FormatError 'Could not render to ...', so the raw NotImplementedError means render was invoked on the format object directly.","triggerScenarios":"obj.render(:msgpack) or Puppet::Network::FormatHandler.format(:msgpack).render(obj) where the class lacks to_msgpack — e.g. the msgpack gem not loaded so the model never got msgpack renderers, or a custom class that only defines to_json.","commonSituations":"Agents or masters requesting msgpack when one side lacks the gem; custom models on FormatSupport without to_data_hash; refactors that dropped a to_* method; formats added by plugins absent on the rendering node.","solutions":["Implement the renderer on the model. For FormatSupport classes the cheapest correct fix is defining to_data_hash — FormatSupport derives to_json/to_msgpack from it.","Switch to a format the class supports: pick from obj.class.supported_formats / default_format instead of a hardcoded name.","Install and load the optional serialization gem (msgpack) so Puppet registers those renderers for the model.","Verify pluginsync delivered any custom format code to the node doing the rendering."],"exampleFix":"# before\nclass Widget\n  include Puppet::Network::FormatSupport\nend\nWidget.new.render(:json) # Widget does not respond to to_json\n\n# after\nclass Widget\n  include Puppet::Network::FormatSupport\n  def to_data_hash = { 'id' => @id, 'name' => @name } # FormatSupport builds to_json/to_msgpack on this\nend","handlingStrategy":"type-guard","validationCode":"fmt_name = Widget.supported_formats.include?(:msgpack) ? :msgpack : Widget.default_format\npayload = Widget.new.render(fmt_name)","typeGuard":"def renderable?(instance, format_name)\n  fmt = Puppet::Network::FormatHandler.format(format_name)\n  !fmt.nil? && instance.respond_to?(fmt.render_method)\nend","tryCatchPattern":"begin\n  instance.render(:json)\nrescue Puppet::Network::FormatHandler::FormatError, NotImplementedError => e\n  # message names the class and missing render method — fall back to the default format\n  instance.render(instance.class.default_format)\nend","preventionTips":["Define to_data_hash on every FormatSupport model; the standard renderers hang off it.","Never pass client-supplied format names straight to render; validate against supported_formats.","Load optional serialization gems (msgpack) uniformly across the fleet.","Test render + convert_from round-trips for each advertised format."],"tags":["puppet","ruby","serialization","formats","rendering","interface"],"backgroundTag":"missing-interface-method","analyzedSha":"e227c27540975c25aa22d533a52424a9d2fc886a","analyzedAt":"2026-08-21T20:49:46.650Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}