Fix Common Errors

Fix NameError: Uninitialized Constant Ruby

NameError uninitialized constant Ruby scope: causes, fixes, and how to catch it in production with LightTrace error tracking and traces.

A NameError: uninitialized constant in Ruby happens when your code tries to reference a class, module, or constant that hasn't been loaded or defined yet. Unlike some languages that fail at compile time, Ruby's dynamic nature means this error appears at runtime—often deep in production. This catches developers off guard because the constant exists somewhere in your codebase, but Ruby's loader hasn't seen it yet. Understanding how Ruby resolves constants through scope and namespace is the key to fixing these errors and preventing them from reaching your users.

The "uninitialized constant" error is deceptively simple on the surface: you used a name that Ruby doesn't recognize. But the root cause can be any of several things—a missing require, a typo, namespace confusion in a Rails app with autoloading quirks, or a constant defined in a scope your code can't see. Once you understand Ruby's constant lookup path and learn to read the stack trace properly, these become straightforward to hunt down.

What is NameError: Uninitialized Constant?

When Ruby encounters a constant name (any identifier starting with a capital letter), it looks it up in a specific order: the current class, the enclosing module hierarchy, then the top-level namespace. If it finds nothing, it raises NameError: uninitialized constant, and the error message tells you exactly which constant it couldn't find—and crucially, in which scope.

class MyApp
  def initialize
    puts CONFIG  # NameError: uninitialized constant MyApp::CONFIG
  end
end

MyApp.new

Here, Ruby looked for CONFIG in MyApp's scope, didn't find it, and told you so. That's actually helpful—the error message is telling you where Ruby looked. The problem is that CONFIG exists somewhere, maybe at the top level, but Ruby's name-resolution rules didn't find it there.

The Most Common Cause: Missing require or require_relative

The single most common cause is forgetting to load the file that defines the constant. Ruby doesn't automatically know about all your files; you have to explicitly load them.

# app.rb
puts User.new  # NameError: uninitialized constant User

# user.rb
class User
  attr_reader :name
  def initialize(name)
    @name = name
  end
end

This fails because app.rb never loaded user.rb. The fix is simple: add a require at the top.

# app.rb
require_relative './user'

puts User.new("Alice")  # Works!

Use require_relative for files in your own project—it's relative to the current file's location. Use require for gems and standard library code.

In a Rails app, this is rarer because Rails autoloads constants for you (by convention). But if you have code outside the standard app/ directory, or if autoloading isn't configured, you'll hit this.

Typos and Name Case Sensitivity

A typo in the constant name is the second-most common culprit. Ruby constants are case-sensitive, and mixing up underscores vs. camelCase will break lookups.

require_relative './user'

puts USER.new  # NameError: uninitialized constant USER
puts User.new  # Works—correct case

This is where the did_you_mean gem comes in handy. If you have it installed (it's a default gem in modern Ruby), it will suggest corrections:

NameError: uninitialized constant USER
Did you mean? User

Enable it early in development by adding this to your Gemfile or startup code:

require 'did_you_mean'

The gem catches typos before they slip into production, saving you from the embarrassment of a simple misspelling taking down a service.

Scope and Namespace Confusion

Scope matters. If you define a constant inside a class or module, that constant is scoped to that namespace. Code outside can't see it unless it uses the fully qualified name. This is one of the most subtle sources of NameError: uninitialized constant Ruby scope issues.

module Payment
  class Processor
    API_KEY = "secret123"
  end
end

# This fails:
puts API_KEY  # NameError: uninitialized constant API_KEY

# This works:
puts Payment::Processor::API_KEY  # "secret123"

Many developers expect constants to be global, but they're not. A constant defined in a class is part of that class's namespace. If you want it accessible everywhere, define it at the top level:

API_KEY = "secret123"

module Payment
  class Processor
    def call
      puts API_KEY  # Works—walks up to top-level scope
    end
  end
end

When you nest classes and modules, Ruby searches up the hierarchy. But it does not cross module boundaries sideways. If you have two unrelated modules, a constant in one isn't visible to the other. The :: prefix lets you escape this and access the global scope:

module PaymentA
  PROVIDER = "Stripe"
end

module PaymentB
  def fetch_provider
    puts ::PROVIDER  # Won't find PaymentA::PROVIDER; looks at root level
  end
end

This is similar in nature to scope issues in other languages—Python developers often encounter nonetype errors when variables aren't initialized, and Java developers face NullPointerException for similar reasons, though the mechanics differ.

Autoloading Pitfalls in Rails

Rails autoloading is convenient but occasionally confusing. Rails will auto-require files based on class names—User loads app/models/user.rb, UsersController loads app/controllers/users_controller.rb, and so on. But autoloading only happens during the request lifecycle in development; in production, it's all eager-loaded at boot. Understanding this difference is crucial to debugging production errors.

A common mistake: using a class from another app/ directory before it's been required. In development, a request loads it just in time. In production, if you reference it in an initializer or at startup, it might not be loaded yet.

# config/initializers/my_initializer.rb
puts User.count  # May fail in production if eager_load_paths isn't set right

The safest pattern is explicit requires in production-critical code, and always test your full boot sequence:

bundle exec rails runner "puts User.count"

This forces a full boot and will catch missing requires before production.

How to Debug NameError in Your Code

When you hit a NameError: uninitialized constant, follow these steps:

  1. Read the error message carefully. It tells you which constant failed and in which scope. NameError: uninitialized constant MyClass::SomeConstant is very different from NameError: uninitialized constant SomeConstant.

  2. Check the stack trace. Line one usually points to the code that triggered the lookup. Trace backward from there.

  3. Verify the constant exists. Use defined? to check:

defined?(User)  # Returns nil if User isn't defined, otherwise returns a string like "constant"

if defined?(User)
  puts User.new
else
  puts "User not loaded yet"
end
  1. Add a require if missing. Check the file where the constant is defined, then require it at the top of the file that needs it.

  2. Check your spelling and case. Use grep -r "class User" . to find where User is actually defined, then verify you're using the exact same name.

  3. In Rails, run a console session. Boot rails console and manually require the file to confirm it works:

rails console
> require_relative 'app/models/user'
> User.new

Preventing Uninitialized Constant Errors

Use explicit requires. Even in Rails, being explicit is clearer than relying on autoloading. Require dependencies at the top of each file.

Enable the did_you_mean gem. It catches typos before they bite you:

gem 'did_you_mean'

Test your boot sequence. Before deploying, run your app in production mode locally:

RAILS_ENV=production bundle exec rails runner 'puts "Booted"'

Leverage error tracking to catch and analyze NameError. Set up error tracking with LightTrace to catch NameError in production and group them by constant name and scope. You'll spot patterns—such as "all NameErrors for MISSING_CONFIG come from the same line"—that point to a single source. This pairs with error tracking best practices like tagging errors by feature or environment so you can filter by context.

Avoid dynamic constant definition. This is a trap:

# Bad—hard to track, confuses the runtime:
const_set(:User, Class.new)

# Good—explicit, easily greppable:
class User
end

Dynamic constants are almost never worth the complexity.

Ruby's constant lookup can feel magical, but it's predictable once you understand the rules: lexical scope first, then the inheritance chain, then top-level. Typos and missing requires account for 90% of real-world NameError: uninitialized constant Ruby scope bugs. The other 10% are scope surprises. Read the error message, check the stack trace, verify the constant's definition, and confirm it's being required. You'll fix these in seconds.

Start tracking errors in minutes

Catch NameError: uninitialized constant and other runtime errors before they reach production. Start free with LightTrace—see full stack traces, understand the exact state of your app when errors occur, and fix them faster.

Fix your next production error faster

Point any Sentry SDK at LightTrace — free up to 5,000 events/month.