48

After I upgrade to OS10.14, I got this error when I called Httparty

    response = HTTParty.get('http://api.stackexchange.com/2.2/questions?site=stackoverflow')
objc[4182]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[4182]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

I already tried export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES before I start rails console.

But it didn't work.

rj487
  • 4,476
  • 6
  • 47
  • 88

5 Answers5

71

It is not enough running the workaround command before rails console.

The following solution worked for me (follow this instructions):

If you encounter this error, you can add the code below to your .bash_profile located in your home directory to fix the issue.

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
  1. Open your terminal
  2. Navigate to your home directory by typing cd ~
  3. Open .bash_profile in an editor (code for VS Code, atom for Atom, vim, nano, etc.) nano .bash_profile
  4. Copy and paste in export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES in your file (be sure it is above the RVM section at the bottom of the file!)

* THIS IS IMPORTANT * In my case into .bash_profile it is something like this:

export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM$

Save the file and quit all editor and terminal sessions. Reopen your editor and everything should now work normally.

I found this solution at this link Kody Clemens Personal Blog

ecbrodie
  • 11,246
  • 21
  • 71
  • 120
jcgil
  • 1,542
  • 1
  • 13
  • 8
  • 4
    This problem just started happening for me randomly when trying to run Spring commands for Rails. Adding this export to the top of my `.zshrc` file helped me out -- thanks! – aardvarkk Nov 29 '19 at 18:55
  • 3
    Also, restart your terminal after making this change. – Andrew Koster Dec 02 '19 at 01:11
  • 2
    This doesn't look like a solution, but instead a hacky workaround, cause – while it makes the error go away – it doesn't fix the root cause and [breaks fork-safety guarantees](http://sealiesoftware.com/blog/archive/2017/6/5/Objective-C_and_fork_in_macOS_1013.html). I experienced the same issue when running `rails db:migrate:status` after doing `brew upgrade`, which updated all of my packages including `gcc`. I don't have a solution yet. – dskecse Dec 02 '19 at 09:49
  • @dskecse did you find a solution? – Marklar Jan 09 '20 at 02:43
  • This isn't even a hacky workaround, it's just straight up dangerous. Apple put fork safety check in there for a reason. Disable this check at your own peril. – James H Aug 05 '22 at 03:17
57

There is a thread on Ruby bugs tracking system about this issue!

https://bugs.ruby-lang.org/issues/14009

basically... As you probably already know, forking (but without exec'ing) in a multithreaded environment is inherently dangerous and the environment must be carefully written to support such a thing. Apple's Objective-C libraries have traditionally not supported being called in a forked (but not exec'd) child process at all, but since High Sierra 10.13 they've tried to add limited support for this. However in doing so they've also defined rules on what is not allowed after forking. One of the rules state that it is not allowed to call the initialize function of certain Objective-C classes after forking; that may only happen before forking.

Makes sense so far. The problem occurs because of a combination of three things:

Ruby itself is not linked to any Objective-C libraries, and so does not initialize Objective-C classes by itself. The user may use gems that do link to Objective-C libraries. Due to how these gems are used, it can occur that these gems end up calling Objective-C initializers after the app server has forked. The new Apple-enforced rule checks then abort the process with a warning like this:

objc[81924]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called.
objc[81924]: +[__NSPlaceholderDictionary initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.

By itself, Apple's error check makes sense. Forking is dangerous. But all these factors combined make less sense. Adding a workaround in Ruby (in the form of ensuring that Objective-C initializers are called before forking) will at least ensure that we return to pre-High Sierra behavior.

There are a lot of solutions in the thread and you would need the one that is specific for your environment/installed gems.

What worked for me was export DISABLE_SPRING=true

  • 1
    Thanks for the detailed write up. I was surprised to see 0 votes, then noticed that you answered it just a while back. – Ashwani Agarwal Dec 13 '19 at 08:27
  • 23
    `export DISABLE_SPRING=true` worked for me. Thanks! – M-Dahab Jan 01 '20 at 18:56
  • 1
    Using DISABLE_SPRING=true "works" because many Rails projects have the Spring gem installed, and it makes extensive use of Process.fork, which is related to forking problem described here. However, keeping Spring installed but always disabled doesn't seem like an ideal solution. If you're not going to use Spring you might as well just remove the gem from your Gemfile. Also, Spring is also not the only thing that could be effected. I've seen this happen with Puma as well. I used OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES instead, which works, and allows me to continue to use Spring. – Adam Apr 07 '23 at 05:42
7

I was facing this issue with OS Mojave and ruby-2.4.0. I made it work by upgrading to ruby-2.4.4. I have posted answer here as well. Oracle instant client with gem ruby-oci8 not able to connect with DB in rails c

Bloomberg
  • 2,317
  • 2
  • 25
  • 47
4

This error started when I upgraded to MacOS Monterey.
Running in your terminal export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES as said before, works and you may also want to add this line to your .zshrc file by running in your terminal: vim ~/.zshrc

jas-chu
  • 525
  • 5
  • 4
1

Simple run this in terminal:

export DISABLE_SPRING=true

Or for a permanent fix, add the above to ~/.zshrc

Jeremy Lynch
  • 6,780
  • 3
  • 52
  • 63