I just installed a clean Mavericks installation with Homebrew and RVM. Both brew doctor
and rvm requirements
return "all good", however, when I run bundle install
in my project dir most of my gems install fine, but a handful fail to install with the same following error:
Bundler::GemspecError: Could not read gem at /Users/NK/.rvm/gems/ruby-2.0.0-p353/cache/eventmachine-1.0.3.gem. It may be corrupted.
An error occurred while installing eventmachine (1.0.3), and Bundler cannot continue.
Make sure that `gem install eventmachine -v '1.0.3'` succeeds before bundling.
Then, if I try again with gem install eventmachine -v '1.0.3'
I get:
ERROR: Error installing eventmachine:
invalid gem: package is corrupt, exception while verifying: undefined method `path2class' for #<Psych::ClassLoader:0x000001018f7990> (NoMethodError) in /Users/NK/.rvm/gems/ruby-2.0.0-p353/cache/eventmachine-1.0.3.gem
I tried to implode RVM and reinstall, but nothing helps.
Other people seem to have the same problem, but no one seems to have fund the answer yet:
- http://pastebin.com/LV53GdR2
- Install Rails Error "invalid gem: package is corrupt"
- Error install rubyracer with error "invalid gem: package is corrupt"
EDIT
See those two as well:
- https://github.com/tenderlove/psych/issues/182
- https://github.com/wayneeseguin/rvm/issues/2620
It turns out that this is a bug in an older version of psych, but it can't be solved, as long as you installed ruby with RVMs statically linked gems. So basically the problem is related to RVMs statically linked gems. Installing rubies with the --disable-binary
solves the problem:
rvm install 2.0.0-p353 --disable-binary
Or reinstall with:
rvm reinstall 2.0.0-p353 --disable-binary
I had the very same error and looked into the psych gem
$ gem list --local | grep psych
psych (2.0.4, 2.0.0)
as version 2.0.4 was recently installed I removed it, keeping only version 2.0.0
$ gem uninstall psych -v '2.0.4'
Successfully uninstalled psych-2.0.4
After that, everything worked fine again!
Immediate Cause
psych.so
is not located at the proper location.
Solution/Workaround
In my case,
cp /usr/local/share/ruby/gems/2.0/gems/psych-2.0.13/lib/psych.so \
/usr/share/ruby/vendor_ruby/2.0/
Details
path2class
method is defined in psych_to_ruby.c
and registered into Psych::ClassLoader
class as a private method by rb_define_private_method()
. The following is the code. Take a look at the last line of Init_psych_to_ruby()
function.
static VALUE path2class(VALUE self, VALUE path)
{
#ifdef HAVE_RUBY_ENCODING_H
return rb_path_to_class(path);
#else
return rb_path2class(StringValuePtr(path));
#endif
}
void Init_psych_to_ruby(void)
{
VALUE psych = rb_define_module("Psych");
VALUE class_loader = rb_define_class_under(psych, "ClassLoader", rb_cObject);
VALUE visitors = rb_define_module_under(psych, "Visitors");
VALUE visitor = rb_define_class_under(visitors, "Visitor", rb_cObject);
cPsychVisitorsToRuby = rb_define_class_under(visitors, "ToRuby", visitor);
rb_define_private_method(cPsychVisitorsToRuby, "build_exception", build_exception, 2);
rb_define_private_method(class_loader, "path2class", path2class, 1);
}
Init_psych_to_ruby()
is called from Init_psych()
function, which is defined in psych.c
.
void Init_psych(void)
{
mPsych = rb_define_module("Psych");
rb_define_singleton_method(mPsych, "libyaml_version", libyaml_version, 0);
Init_psych_parser();
Init_psych_emitter();
Init_psych_to_ruby();
Init_psych_yaml_tree();
}
Ruby calls Init_{library}()
function after it loads the library's shared library (.so file). So, in the case of psych, if psych.so
is found and loaded, Init_psych()
function is called and in turn Init_psych_to_ruby()
is called, and finally path2class
is registered. However, if psych.so
does not exist, path2class
is never registered and you will see the error message "undefined method `path2class'".
Probably, there is something wrong in the packaging process of either psych or Ruby.
I was having the same problem and remembered that XCode had been updated recently. I was reminded of this because some Terminal output claimed that the developer tools were not installed and suggested running the following:
$ xcode-select --install
It still wasn't working so I used rvm to install the latest 2.1 version of Ruby, created a new gemset, pointed my app to use that gemset and ran $ bundle install
. It now works.
For me this turned out to be a permissions issue. I fixed it by resetting my permissions on my ~/.rvm
folder. Mac OS X 10.9.3.
First, find your system username:
ls -lA ~ | head
Produces:
-rw-r--r--@ 1 nperry staff 43012 Jul 1 13:25 .DS_Store
drwx------ 63 nperry staff 2142 Jul 1 13:40 .Trash
...
My username is nperry
and my group is staff
. Change the following lines to match your user and group.
sudo chown -R nperry:staff ~/.rvm
sudo chmod -R ug+rw ~/.rvm
And no more errors.
This is not a particularly insightful answer, but in my case the problem went away by switching to ruby-2.1.2
(p95, incidentally) via rvm
.
I was going to upgrade anyway...