{"record":{"id":"b6d22d3ca3f6241a","repo":"ViewComponent/view_component","slug":"cannot-serialize-slot-call-method-name-with-a","errorCode":null,"errorMessage":"Cannot serialize slot call '#{method_name}' with a block","messagePattern":"Cannot serialize slot call '#(.+?)' with a block","errorType":"exception","errorClass":"ViewComponent::Serializable::UnserializableError","httpStatus":null,"severity":"error","filePath":"lib/view_component/serializable/proxy.rb","lineNumber":94,"sourceCode":"      end\n\n      if defined?(Rails::VERSION) && Rails::VERSION::MAJOR == 7 && Rails::VERSION::MINOR == 1\n        # Rails expects us to define `format` on all renderables,\n        # but we do not know the `format` of a ViewComponent until runtime.\n        def format\n          nil\n        end\n      end\n\n      private\n\n      def slot_method?(method_name)\n        method_name.to_s.start_with?(\"with_\") && @component_class.method_defined?(method_name)\n      end\n\n      def capture_slot_call(method_name, args, &block)\n        if block\n          raise UnserializableError, \"Cannot serialize slot call '#{method_name}' with a block\"\n        end\n\n        @slot_calls << {method: method_name, args: args}\n        self\n      end\n\n      def build_component\n        @component_class.new(*@initialize_args).tap do |instance|\n          @slot_calls.each do |call|\n            instance.public_send(call[:method], *call[:args])\n          end\n        end\n      end\n    end\n  end\nend\n","sourceCodeStart":76,"sourceCodeEnd":111,"githubUrl":"https://github.com/ViewComponent/view_component/blob/9f22c36fa7d7b44098a8ed97472e3b4674ae420f/lib/view_component/serializable/proxy.rb#L76-L111","documentation":"Slot calls on a render_later Proxy are captured by method_missing and replayed at render time, but only as (method, args) pairs stored in slot_calls — a Ruby block cannot be captured that way. capture_slot_call therefore raises ViewComponent::Serializable::UnserializableError (\"Cannot serialize slot call 'with_x' with a block\") when a with_* slot method is invoked with a block on the proxy. Slot content must be passed as serializable arguments.","triggerScenarios":"MyComponent.render_later(...).with_item { \"content\" }; calling with_item(label: \"One\") { |item| ... } on the proxy; porting block-style slot usage from a concrete component to the deferred proxy.","commonSituations":"Components whose slots normally receive blocks in templates (renders_many :items with block content); moving Turbo Stream renders into jobs while keeping block-based slot calls; helper methods that always attach a block to slot setters.","solutions":["Drop the block and pass the content as an argument the slot accepts: .with_item(label: \"One\", body: \"Body text\").","If the slot normally takes a block, redesign it to accept content as plain data (or a nested deferred component) rather than a block.","If block semantics are required, build and render the real component synchronously instead of the proxy."],"exampleFix":"# before\nproxy = MyComponent.render_later(\"title\").with_item(label: \"One\") do\n  \"<span>Block body</span>\"\nend # UnserializableError on slot call\n\n# after\nproxy = MyComponent.render_later(\"title\").with_item(label: \"One\", body: \"<span>Block body</span>\")","handlingStrategy":"validation","validationCode":"def with_serializable_slot(proxy, method_name, *args, &block)\n  raise ArgumentError, \"slot calls on a deferred proxy cannot take blocks\" if block\n  proxy.public_send(method_name, *args)\nend","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Design slots used with render_later to accept content as keyword/positional args, not blocks.","Pass plain data (strings, hashes) or defer nested components via their own render_later proxy.","Lint for `.with_...` calls followed by a block near render_later usage."],"tags":["view-component","ruby-on-rails","slots","serialization","activejob"],"backgroundTag":"block-not-serializable","analyzedSha":"9f22c36fa7d7b44098a8ed97472e3b4674ae420f","analyzedAt":"2026-08-23T10:20:47.008Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}