In Ruby on Rails, why does rendering a nested partial fail with a ‘missing partial’ error, even though the file exists?
In app/views/registrations/_new.html.erb, there is:
<%= render 'municipals/autocomplete.html.erb' %>
The file app/views/municipals/autocomplete.html.erb exists in the correct directory. However, rendering registrations/_new.html.erb produces the error:
Missing partial municipals/_autocomplete.html.erb
Moving the render call to the parent view (which renders registrations/new.html.erb) works without error.
Are there restrictions on nested partial rendering in Rails? Why is Rails looking for municipals/_autocomplete.html.erb instead of autocomplete.html.erb?
Rails (Ruby on Rails) expects partials to be named with a leading underscore and to be referenced without a file extension; when you call render 'municipals/autocomplete.html.erb' Rails treats that as a partial name, prefixes an underscore and looks for municipals/_autocomplete.html.erb. There’s no special restriction on nested partials — the error usually means either the file is missing the underscore, you passed the extension (which can confuse lookup), or the requested format/lookup context differs. Fix by renaming to app/views/municipals/_autocomplete.html.erb and calling render 'municipals/autocomplete' (or use render partial: '/municipals/autocomplete').
Contents
- Short answer: Ruby on Rails, nested partials and the “Missing partial” error
- How Rails resolves partial paths and render lookup
- Why this produced “Missing partial municipals/_autocomplete.html.erb”
- Quick fixes: correct render calls and filenames
- Troubleshooting checklist and advanced notes
- Sources
- Conclusion
Short answer: Ruby on Rails, nested partials and the “Missing partial” error
No — Rails does not forbid nested partials. The framework is simply following its partial lookup rules. Partials must be named with an initial underscore (for example _autocomplete.html.erb) and you should call them without the extension (for example render 'municipals/autocomplete'). Rails will automatically add the underscore and resolve the correct handler/format, so if your file is named autocomplete.html.erb (no underscore) Rails will fail with “Missing partial municipals/_autocomplete.html.erb.” The Rails Guides explain this naming and lookup convention in detail: see the partials section in the Layouts and Rendering guide.
How Rails resolves partial paths and render lookup
Briefly, the view renderer converts the string you give it into a lookup path using the current lookup context. The renderer:
- Treats
render 'folder/name'as a request for the partial_nameinapp/views/folder/. - Automatically prefixes the filename with
_and appends the current format and template handler (for example.html.erbor.js.erb). - Uses the current view/controller lookup context unless you pass an absolute path (leading
/) or use explicit options likepartial:orfile:.
The Rails API implementation for this is in ActionView’s PartialRenderer, which explains how partial names are mapped to template files and how formats/handlers are resolved: https://api.rubyonrails.org/classes/ActionView/PartialRenderer.html. A simple mapping example:
render 'municipals/autocomplete'→ looks forapp/views/municipals/_autocomplete.html.erb(assuming HTML format)render 'autocomplete'insideapp/views/municipals/_form.html.erb→ looks forapp/views/municipals/_autocomplete.html.erb(relative lookup)render partial: '/municipals/autocomplete'→ forces an absolute lookup fromapp/views/municipals/_autocomplete...
(For a compact example of render → filesystem mapping see this gist: https://gist.github.com/wangjohn/5418350.)
Why this produced “Missing partial municipals/_autocomplete.html.erb”
Your snippet:
<%= render 'municipals/autocomplete.html.erb' %>
does three problem-causing things:
- Rails expects a partial name, so it looks for a file prefixed with
_— i.e.,municipals/_autocomplete(then the correct format/handler). - You passed the full extension
.html.erbin the render call. Rails prefers you omit the extension; including it can change lookup behavior and produce confusing errors (this has bitten other users and is discussed in Rails issues — see https://github.com/rails/rails/issues/5025). - Your existing file is
app/views/municipals/autocomplete.html.erb(no underscore), so there is noapp/views/municipals/_autocomplete.html.erbfor Rails to find.
Why did moving the render call to the parent view sometimes “work”? There are a few plausible reasons:
- In some contexts Rails may fall back to a template lookup or a different lookup path when rendering from a top-level template versus a nested partial; passing the extension or calling from a different lookup context can change which search paths Rails tries (see related lookup-context/namespacing issues: https://github.com/rails/rails/issues/29468).
- Sometimes a precompiled template or a helper pre-render (gems may pre-render or cache partials) can mask the problem when called from a different spot.
But the most reliable and correct fix is to follow convention: name partials with _ and call them without the extension.
Quick fixes: correct render calls and filenames
Do this (recommended):
- Rename the file to a partial name:
app/views/municipals/_autocomplete.html.erb
- Call the partial without the extension:
<%= render 'municipals/autocomplete' %>
- Or be explicit (absolute path or partial option):
<%= render partial: '/municipals/autocomplete' %>
# or
<%= render partial: 'municipals/autocomplete' %>
Other options (less conventional):
- If you intentionally want to render a full template file (not a partial), use
render file: 'municipals/autocomplete'orrender template: 'municipals/autocomplete'— but this is atypical for small reusable snippets. - If the partial is used for a different format (AJAX/JS), create the matching handler:
app/views/municipals/_autocomplete.js.erbor specify formats:render 'municipals/autocomplete', formats: [:js].
If you’re using helper gems that pre-render or buffer partials (for example some form helper libraries), make sure they’re pointed at the partial name (with underscore) — see this related cocoon discussion: https://github.com/nathanvda/cocoon/issues/50.
Troubleshooting checklist and advanced notes
- Check the filename: does it start with
_? If not, rename it. - Remove the
.html.erbfrom yourrendercall — render partials by name only. - Look at the full error message; Rails prints “Searched in:” with the exact paths it checked — that often points to the mismatch.
- Confirm the requested format: if the request is JS, Rails will search for
_autocomplete.js.erbrather than_autocomplete.html.erb. - Restart the server / Spring if you changed filenames and Rails still claims the file is missing — development caching can cause stale lookups.
- If the partial is inside a namespaced controller or you’ve got unusual view paths, check the lookup_context or use an absolute path (
/municipals/autocomplete). - If a helper or gem is involved, check whether it pre-renders the partial and whether it expects a specific partial name (underscore + path).
Community Q&A threads and issue reports that describe the same pitfall can be helpful when you hit odd behavior: see these examples on Stack Overflow and GoRails for similar patterns and fixes — https://stackoverflow.com/questions/79866913/partial-referencing-partial-not-found and https://gorails.com/forum/missing-partial-error-even-though-lookup-context-comes-back-as-true.
Sources
- https://guides.rubyonrails.org/layouts_and_rendering.html
- https://api.rubyonrails.org/classes/ActionView/PartialRenderer.html
- https://github.com/rails/rails/issues/5025
- https://github.com/rails/rails/issues/29468
- https://stackoverflow.com/questions/12749466/my-partial-is-not-where-rails-expects-it-to-be-nested-partials
- https://stackoverflow.com/questions/79866913/partial-referencing-partial-not-found
- https://gorails.com/forum/missing-partial-error-even-though-lookup-context-comes-back-as-true
- https://gist.github.com/wangjohn/5418350
- https://github.com/nathanvda/cocoon/issues/50
- https://stackoverflow.com/questions/35132559/why-does-a-missing-partial-error-occur-occasionally-when-the-file-exists
- https://whatibroke.com/tag/partials/
Conclusion
There’s no special ban on nested partials in Ruby on Rails — the framework is doing exactly what it’s told: when you ask to render a partial, Rails adds an underscore and resolves format/handler using the current lookup context. In your case the simplest, correct fix is to rename the file to _autocomplete.html.erb and call render 'municipals/autocomplete' (or render partial: '/municipals/autocomplete'). If that doesn’t solve it, check formats, lookup paths, and any helper/gem that might pre-render the partial, then paste the full “Searched in:” output and I’ll help you track the exact lookup Rails is trying.