{"record":{"id":"75953f63535f8ea6","repo":"ViewComponent/view_component","slug":"it-looks-like-a-block-was-provided-after-calling-75953f","errorCode":null,"errorMessage":"It looks like a block was provided after calling `with_content` on COMPONENT, which means that ViewComponent doesn't know which content to use.\n\nTo fix this issue, use either `with_content` or a block.","messagePattern":"It looks like a block was provided after calling `with_content` on COMPONENT, which means that ViewComponent doesn't know which content to use\\.\n\nTo fix this issue, use either `with_content` or a block\\.","errorType":"exception","errorClass":"ViewComponent::DuplicateSlotContentError","httpStatus":null,"severity":"error","filePath":"lib/view_component/slot.rb","lineNumber":51,"sourceCode":"    #\n    # There's currently 3 different values that may be set, that we can render.\n    #\n    # If the slot renderable is a component, the string class name of a\n    # component, or a function that returns a component, we render that\n    # component instance, returning the string.\n    #\n    # If the slot renderable is a function and returns a string, it's\n    # set as `@__vc_content` and is returned directly.\n    #\n    # If there is no slot renderable, we evaluate the block passed to\n    # the slot and return it.\n    def to_s\n      return @content if defined?(@content)\n\n      view_context = @parent.send(:view_context)\n\n      if defined?(@__vc_content_block) && defined?(@__vc_content_set_by_with_content)\n        raise DuplicateSlotContentError.new(self.class.name)\n      end\n\n      @content =\n        if __vc_component_instance?\n          @__vc_component_instance.__vc_original_view_context = @parent.__vc_original_view_context\n\n          if defined?(@__vc_content_block)\n            # render_in is faster than `parent.render`\n            @__vc_component_instance.render_in(view_context) do |*args|\n              @parent.with_captured_virtual_path(@__vc_content_block_virtual_path) do\n                @__vc_content_block.call(*args)\n              end\n            end\n          else\n            @__vc_component_instance.render_in(view_context)\n          end\n        elsif defined?(@__vc_content)\n          @__vc_content","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/ViewComponent/view_component/blob/9f22c36fa7d7b44098a8ed97472e3b4674ae420f/lib/view_component/slot.rb#L33-L69","documentation":"A ViewComponent::Slot can receive content two ways: a block captured at render time (@__vc_content_block) or a value set via with_content (@__vc_content_set_by_with_content). When Slot#to_s renders and both are defined, ViewComponent cannot know which content wins and raises ViewComponent::DuplicateSlotContentError. This is by design: content must be unambiguous, so use either with_content or a block — never both on the same slot.","triggerScenarios":"Calling with_content on a slot and also passing a block: c.with_header.with_content(\"Title\") do ... end; slot setters invoked with both a content value and a block (with_header(\"Title\") { \"Block\" }); templates that wrap a with_content call in a block-bearing render helper.","commonSituations":"Refactoring slot content from blocks to with_content (or vice versa) and leaving both paths active; conditional templates that set content in one branch and yield a block in another; helper wrappers that auto-attach with_content while the caller also passes a block.","solutions":["Pick one mechanism: delete the with_content call and keep the block, or keep with_content and delete the block.","If content is conditional, branch on the same condition for both paths so only one is ever active (set content OR pass block, never both).","Audit wrapper helpers that call with_content internally when callers may also supply a block."],"exampleFix":"# before (ERB)\n<%= render(MyComponent.new) do |c| %>\n  <%= c.with_header.with_content(\"Title\") do %>\n    Block content\n  <% end %>\n<% end %>\n\n# after (ERB)\n<%= render(MyComponent.new) do |c| %>\n  <%= c.with_header.with_content(\"Title\") %>\n<% end %>","handlingStrategy":"validation","validationCode":"# Before setting slot content, pick exactly one mechanism\nslot = component.with_header\nif slot.respond_to?(:content?) && slot.content?\n  # already has block/content: do not call with_content\nelse\n  slot.with_content(\"Title\")\nend","typeGuard":null,"tryCatchPattern":"begin\n  render(MyComponent.new) do |c|\n    c.with_header { \"Block\" }\n  end\nrescue ViewComponent::DuplicateSlotContentError\n  raise \"header slot got with_content AND a block; remove one\"\nend","preventionTips":["One content source per slot: choose with_content or a block per call site and never mix.","When refactoring from blocks to with_content, remove the block in the same change.","In wrapper helpers, document and assert they own exactly one of the two content paths."],"tags":["view-component","ruby-on-rails","slots","content-ambiguity","duplicate-content"],"backgroundTag":"duplicate-content-definition","analyzedSha":"9f22c36fa7d7b44098a8ed97472e3b4674ae420f","analyzedAt":"2026-08-23T10:20:47.008Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}