ViewComponent/view_component · error · ViewComponent::ControllerCalledBeforeRenderError
`#controller` can't be used before rendering, as it depends
Error message
`#controller` can't be used before rendering, as it depends on the view context that only exists once a ViewComponent is passed to the Rails render pipeline. It's sometimes possible to fix this issue by moving code dependent on `#controller` to a [`#before_render` method](https://viewcomponent.org/api.html#before_render--void).
What it means
Error "`#controller` can't be used before rendering, as it depends on the view context that only exists once a ViewComponent is passed to the Rails render pipeline. It's sometimes possible to fix this issue by moving code dependent on `#controller` to a [`#before_render` method](https://viewcomponent.org/api.html#before_render--void)." thrown in ViewComponent/view_component.
Source
Thrown at lib/view_component/base.rb:316
# (whose _run allocated a fresh OutputBuffer on the view context), the
# component's stale @output_buffer would capture from the wrong buffer.
# Temporarily switching to the view context's buffer keeps both in sync.
#
# @private
def capture(...)
old_output_buffer = @output_buffer
@output_buffer = view_context.output_buffer if view_context
super
ensure
@output_buffer = old_output_buffer
end
# The current controller. Use sparingly as doing so introduces coupling
# that inhibits encapsulation & reuse, often making testing difficult.
#
# @return [ActionController::Base]
def controller
raise ControllerCalledBeforeRenderError if view_context.nil?
@__vc_controller ||= view_context.controller
end
# A proxy through which to access helpers. Use sparingly as doing so introduces
# coupling that inhibits encapsulation & reuse, often making testing difficult.
#
# @return [ActionView::Base]
def helpers
raise HelpersCalledBeforeRenderError if view_context.nil?
# Attempt to re-use the original view_context passed to the first
# component rendered in the rendering pipeline. This prevents the
# instantiation of a new view_context via `controller.view_context` which
# always returns a new instance of the view context class.
#
# This allows ivars to remain persisted when using the same helper via
# `helpers` across multiple components and partials.View on GitHub (pinned to 9f22c36fa7)
Solutions
- Move code that calls `#controller` into a `#before_render` method (or the template), which only runs once the view context exists.
- If controller data is needed at initialization time, pass it explicitly into the component's initializer instead of reading it via `#controller`.
When it happens
Trigger: Thrown at lib/view_component/base.rb:316 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of ViewComponent/view_component@9f22c36fa7 (2026-08-23).
Data as JSON: /api/errors/38e96c7a33669ec3.
Report an issue: GitHub.