I’m writing this post the minute I fixed a head-scratching Rails setup bug on my own machine. If you’ve just typed bundle install
, watched Nokogiri and Byebug implode in ruby, and wondered what on earth is wrong with your Gemfile, walk with me step-by-step. I’ll show you exactly how I reproduced the failure in a clean folder, why it happens, the two-minute fix, and one extra Rake task I now keep in every project so this never bites me again.
Let Break The App on Purpose
Inside an empty directory I dropped a super-small Gemfile:
# Gemfile
source "https://rubygems.org"
ruby "2.3.0"
gem "rails", "4.2.6"
gem "paperclip"
gem "aws-sdk", "~> 2"
group :development, :test do
gem "byebug", "9.0.6" # this will blow up
gem "sqlite3"
end
Then I ran:
bundle install
And sure enough, the console barked back:
byebug 9.0.6 with native extensions
Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
xcrun: error: invalid active developer path …
An error occurred while installing byebug (9.0.6), and Bundler cannot continue.
Right above that I also spotted Nokogiri 1.6.8.1 compiling, despite not being anywhere in my Gemfile.
Perfect bug reproduced.
Why is Nokogiri Even Here?
Short answer: Rails drags it in for HTML testing.
rails ➜ actionpack ➜ actionview ➜ rails-dom-testing ➜ nokogiri
Long answer: if an old Gemfile.lock
lives in the folder, Bundler re-uses it and you’ll see ghosts of gems you once needed. Deleting the lock file forces Bundler to calculate a fresh dependency tree.
Does Byebug Explode?
Both Byebug and Nokogiri ship native C extensions.
On macOS they need Apple’s Command Line Tools (CLT) make
, gcc
, xcrun
, and a stack of header files. The fatal line
xcrun: error: invalid active developer path
screams “CLT not installed” (or wiped during the last macOS update).
The two-minute, three-command fix
# 1. Grab the compilers (≈100 MB, one-time job)
xcode-select --install
# 2. Throw away stale dependency pins
rm -f Gemfile.lock
# 3. Try again
bundle install
If you’re a Homebrew fan, add:
brew install libxml2 libxslt # headers Nokogiri uses
Mission accomplished no errors, gems compiled, server boots.
A Couple of Quick Practice Drills
Prove Byebug Actually Works
Create hello.rb
:
# hello.rb
def greet(name)
message = "Hello, #{name}!"
byebug # pause and poke around
message.upcase!
end
puts greet("world")
Run it:
ruby hello.rb
At the (byebug)
prompt type message
and press Enter you’ll see the variable live, then continue
to finish. Debugger confirmed.
Rake Task That Warns Early
Add a Rakefile
:
# Rakefile
require "rbconfig"
require "bundler"
desc "Check for native gems and presence of a compiler"
task :native_check do
compiler = `which gcc`.strip
if compiler.empty?
puts " gcc not found – native gems will fail!"
exit 1
else
puts " gcc found at #{compiler}"
end
native = Bundler.load.specs.select { |s| s.extensions.any? }
if native.empty?
puts "No native gems in this bundle."
else
puts "Native gems detected:"
native.each { |g| puts " • #{g.name} #{g.version}" }
end
end
Now:
bundle exec rake native_check
If I ever clone this project on a fresh laptop, one command tells me whether I have the tools to build every gem.
Final Thought
I used to blame mysterious build errors on “Rails being Rails,” but nine times out of ten it’s nothing more exotic than a missing compiler or a forgotten lock file. Whenever bundle install
throws a native-extension tantrum, my reflex is now:
- Install build tools (
xcode-select --install
orsudo apt-get install build-essential
) - Nuke
Gemfile.lock
and reinstall.