SECURITY WARNING: Never run commands you don't understand. Always review code before execution. Use at your own risk.
Ruby New Added 26 October 2026

Zeitwerk::NameError: expected file app/models/user.rb to define constant User

Since Rails 7, Zeitwerk is the only autoloader, and it maps every file path to exactly one constant name. The file exists, but the class inside it is named something else: a typo, a module nesting that does not match the folders, or an acronym such as HTMLParser in html_parser.rb, which Zeitwerk expects to be HtmlParser. Code that loaded under the classic autoloader often trips this on upgrade, and production finds files development never touched because it eager loads everything.

Quick fix

Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.

Quick fix
# Check every file the way production eager loads them
bin/rails zeitwerk:check

# Compare the file name with the constant it really defines
grep -nE "^\s*(class|module) " app/models/user.rb

# app/services/billing/invoice.rb must define Billing::Invoice
# app/lib/html_parser.rb must define HtmlParser, unless you add an acronym:
# config/initializers/inflections.rb
#   ActiveSupport::Inflector.inflections(:en) { |i| i.acronym "HTML" }

# Files that define no constant (monkey patches, scripts) should not be
# autoloaded at all. In config/application.rb (Rails 7.1+):
#   config.autoload_lib(ignore: %w[assets tasks patches])

bin/rails zeitwerk:check

How to diagnose Ruby errors

Ruby errors are dominated by Bundler and gem resolution, native extension compilation (which needs system headers Ruby cannot install for you), and in Rails by the pending-migration and asset-precompilation guards. Those guards are deliberate safety checks, so the fix is to satisfy them rather than to disable them.

If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.

  1. Run bundle install with verbose output and read which gem fails and why. Native extension failures name the missing header in the mkmf log.
  2. Check the mkmf log path the error prints. It contains the actual compiler error, which the Bundler summary truncates.
  3. For Rails migration errors, run rails db:migrate:status to see exactly which migrations the database has recorded.
  4. For asset errors in production, confirm rails assets:precompile ran during deployment and that the manifest is present in public/assets.
  5. Verify the Ruby version matches .ruby-version and the Gemfile. Version managers silently switch, producing gem-not-found errors for gems that are installed elsewhere.

Tools worth reaching for

  • bundle install --verbose
  • rails db:migrate:status
  • gem env
  • rbenv/rvm version check
  • bundle exec

Authoritative references

Primary documentation for this error, worth reading before applying any fix in production.

guides.rubyonrails.org github.com

Related Ruby errors

See all 20 Ruby errors →

Browse other categories

Something missing or wrong?

This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.