NoMethodError: undefined method 'email' for nil

Ruby · updated 2026-11-13

Raised when code calls a method on nil. Ruby 3.4 prints undefined method 'email' for nil and points a caret at the call; Ruby 3.3 and older print undefined method `email' for nil:NilClass. The method named is the one you called, not the cause: the question is which expression before it returned nil.

nomethod.rb:4:in 'Object#receipt_email': undefined method 'email' for nil (NoMethodError)

  find_user(id).email.downcase
               ^^^^^^
	from nomethod.rb:6:in '<main>'

Quick fix

Look at the expression just left of the failing call (find_user(id) above) and ask when it returns nil: a record that doesn't exist, a hash key that is missing, an API field left out. If nil is a normal case, handle it (&., dig, or an early return); if it isn't, fail loudly where the value is loaded (find instead of find_by, fetch instead of []).

  1. Read the caret line (Ruby 3.4) or the backtrace line: the receiver of the failing call is the nil.
  2. Find where that value comes from: find_by, where(...).first, a params or hash lookup, or a method whose last line returns nil.
  3. If nil is expected, handle it with safe navigation (user&.email), hash.dig or an explicit early return.
  4. If it is not expected, load it in a way that raises with a clear message: find(id), hash.fetch(:key), or a validation at the boundary.
ruby
# nil is a normal case: handle it
email = find_user(id)&.email
return if email.nil?

# Nested hashes from JSON or params
email = payload.dig(:customer, :email)

# nil is a bug: fail where it is loaded, with a message
user = User.find(id)                 # ActiveRecord::RecordNotFound instead of nil
email = payload.fetch(:customer).fetch(:email)
Fix it with your coding agent

Paste this into Claude Code, Cursor or Codex in the project that throws it. The agent reads this guide in plain text and applies the fix that matches your stack.

prompttext
Read https://runheed.com/errors/ruby-undefined-method-for-nil.md and fix this error in this project.

Why it happens

A lookup found nothing

find_by, where(...).first, Array#find and Hash#[] return nil when nothing matches. The record exists in development and is missing for one user in production.

A params or JSON field is missing

params[:order][:customer] or a parsed API response without the key returns nil, and the next method call fails. Optional fields and API changes are the usual triggers.

A method returns nil on one branch

An if without an else, or a method whose last expression is a puts or a failed assignment, returns nil, and the caller chains a method onto it.

An association is not set

order.customer is nil for orders created before the column existed or by a path that skipped it, so order.customer.email raises.

Other fixes

  • Add belongs_to validations (required by default since Rails 5) and database NOT NULL constraints for values that must exist.
  • Type-check with Sorbet or RBS + Steep to catch possibly-nil receivers before deploy.
  • Use present? and presence for strings that may be nil or empty.

Same error, other wording

  • undefined method `email' for nil:NilClass (NoMethodError)
  • NoMethodError: undefined method `[]' for nil:NilClass
  • undefined method 'each' for nil (NoMethodError)

Let your coding agent catch the next one

Runheed records this error in production with the stack trace, the breadcrumbs before it and, when you set it, the agent session that shipped the code, and serves it to Claude Code, Cursor or any MCP client. With it connected, you can ask:

> Find the NoMethodError for nil exceptions in production, show the line and the request behind the latest one, work out which call returned nil and why, and handle it where the value is loaded.

Setup for Ruby, then have your agent fix and resolve it.

Related errors

More in Undefined, None and type errors

References: Ruby: NoMethodError, Ruby 3.4 release notes: error message format, Ruby: Hash#dig and Hash#fetch

Spotted a mistake? Email hello@greatwork.company. About Runheed.