Note: Do not run any
brew commands on Epicodus computers. Most versioning issues in Ruby/Rails projects are local to the project, not global to the machine. The information below will ensure that your local project environment doesn't conflict with your global environment. If you think that there is an incorrect version of Ruby, Rails, or another tool on an Epicodus machine, please put in a ticket.
In this lesson, we will address a common error that many students run into, both on their personal machines and occasionally the machines at Epicodus.
These issues tend to come up with
rspec commands. If you are having an issue with one of these commands, this should always be your first troubleshooting step!
This is a common error when running a
$ rake rake aborted! Gem::LoadError: You have already activated rake 10.4.2, but your Gemfile requires rake 10.4.0. Prepending `bundle exec` to your command may solve this.
As the error message suggests, this is usually resolved by including
$ bundle exec before the
rake command. Let's address what this error is, why it occurs, and why
bundle exec resolves it.
The error above generally occurs when one version of an executable script run in the command line (such as
rspec) is installed for a project but a different version of the same tool is installed system-wide on the machine. In other words, there is a conflict between the local project's environment and the global environment of the computer you are using.
The error message above reads
"You have already activated rake 10.4.2, but your Gemfile requires rake 10.4.0". This means version 10.4.2 of the rake gem has been installed system-wide but the specific project requires version 10.4.0 in its Gemfile.
We don't want to remove the incompatible system-wide gem to solve this issue. If other projects or tools require that version, we'll only encounter more errors in other projects.
Additionally, we can't guarantee that simply updating our project to use the newest version will work, either. Other gem versions in our project may not be compatible with this new version. Updating a gem in a large project can result in potential headaches.
Instead, we can prepend
bundle exec to our executable script commands. This ensures the executable script uses gem versions from that project's Gemfile, not other versions installed system-wide on the machine.
If we receive an error like the one shown above, we could prepend
bundle exec onto the command like this:
$ bundle exec rake:db migrate
This would ensure that we're using the rake versions specified in the project's Gemfile.
bundle command retrieves all necessary gems in a project's
Gemfile for use with an application. If a project includes a required Gem that isn't available locally, the bundler reaches out to rubygems.org and retrieves it.
Conversely, as detailed in its Bundler documentation entry, the
bundle exec command allows us to run an executable script in the specific context of the project's bundle.
It's important to understand that
bundle exec is not a replacement for the
bundle command we run after adding gems to our Gemfiles. As we saw in the example above, it's a prefix to prepend onto executable script commands like
Developers usually don't update large codebases every single time a new version of a tool is released. Updating a huge project to use the latest version of a gem or library often isn't worth it, especially if the older version still works.
It's likely that you'll eventually find yourself working on codebases that don't use the most recent releases of gems, perhaps even while concurrently developing other projects that do. In these instances,
bundle exec allows us to effortlessly switch between different projects with different gem requirements, ensuring each has access to the version it requires.
For more details, including a few optional tips and shortcuts check out the But I don't want to
bundle exec!_ blog post from the Portland company Thoughtbot.
Additionally, information on this Bundler command and more can always be found in the Bundler documentation
Many Ruby developers always prepend
bundle exec to their commands to ensure there's not a conflict between the local and global environment. While it's a little bit of extra work to type, it can save you a lot of trouble down the road.
Lesson 30 of 34
Last updated July 14, 2022