---
title: "Working with Legacy Ruby on Rails: spring.gem fork() Crash"
description: "Working with Legacy Ruby on Rails projects is a challenge. Fixing a spring gem fork() crash is one step."
url: "https://qameta.com/posts/working-with-legacy-ruby-on-rails-spring-fork-crash/"
image: "https://qameta.com/posts/working-with-legacy-ruby-on-rails-spring-fork-crash/spring-thread-fork-crash.png"
---

# Working with Legacy Ruby on Rails: spring.gem fork() Crash

![Spring Fork Crash on Ruby on Rails](https://qameta.com/posts/working-with-legacy-ruby-on-rails-spring-fork-crash/spring-thread-fork-crash.png)

Working with legacy [Ruby on Rails](https://rubyonrails.org) applications is for
most developers a problem, as they have a lot of extra work to do:

* Use older documentation, which matches the legacy project
* can't use fixes and improvements of programming language
* can't use improvements and features of up-to-date framework version
* have to use older and mostly unsupported third-party extensions
* are maybe forced to write code, which must be changed for updates and upgrades

First of all, many developers will hit the CPU architecture change from
[x86](https://en.wikipedia.org/wiki/X86)/[x64](https://en.wikipedia.org/wiki/X86-64)
to [ARM64](https://en.wikipedia.org/wiki/ARM_architecture_family) using [Apple
Macs](https://www.apple.com/mac/). Even installing older
[Ruby](https://www.ruby-lang.org/en/) versions on a newer OS (operating system)
on a x86/x64 architecture is hard. It produces a lot of problems, warnings, and
errors.

## Understand the crash introduced through a fork() call

If you could install [Ruby](https://www.ruby-lang.org/en/) on your system, the
next thing which may hit you is starting your application using `bin/rails` and
running `bin/rake` commands. If you have ever tried it, this or a similar error
may stop you:

```sh
bin/rake db:schema:load

Called from /Users/developer/.asdf/installs/ruby/2.2.10/lib/ruby/gems/2.2.0/gems/activesupport-4.2.11.1/lib/active_support/dependencies.rb:240:in `load_dependency`
objc[98084]: +[__NSCFConstantString initialize] may have been in progress in another thread when fork() was called.
objc[98084]: +[__NSCFConstantString 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.
```

This change was introduced in [MacOS 10.13 (High
Sierra)](https://en.wikipedia.org/wiki/MacOS_High_Sierra) in 2017. You can have
a deeper reading on it here: [Objective-C and fork() in macOS
10.13](https://sealiesoftware.com/blog/archive/2017/6/5/Objective-C_and_fork_in_macOS_1013.html).
There are a lot of projects, which were hit by this problem like
[Python](https://github.com/python/cpython/issues/77906),
[Passenger](https://blog.phusion.nl/2017/10/13/why-ruby-app-servers-break-on-macos-high-sierra-and-what-can-be-done-about-it/),
and
[Puma](https://github.com/puma/puma/issues/1421).

There may be more issues you need to tackle to get a legacy project running on a
newer system. But how to get this?

## Where does it hit my project?

First of all, you need to figure out, where a new thread was started using
`fork()` command. The message you get does not point you to the line of code or
gem, which causes this crash.

As the project was a common Ruby on Rails project without any threading built
in, the fork must have been called by a third-party gem, which was defined in
the Gemfile (or Gemfile.lock as dependency) and was loaded as dependency on the
start of Ruby on Rails.

I've checked the Gemfile and could only find the [spring
gem](https://rubygems.org/gems/spring), which was using threads to improve
starting the Ruby on Rails and related command line tools like `bin/rake`, as
they were loading the Rails project on start too.

## Stop Initialize Fork Safety on MacOS High Sierra

This won't work on newer MacOS versions. If you are still running MacOS High
Sierra you can stop this safety check by defining the environment variable
`OBJC_DISABLE_INITIALIZE_FORK_SAFETY` in one of these ways:

```sh
# For a single command (on MacOS High Sierra only)
OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES bin/rails s

# Stop it in the current shell (on MacOS High Sierra only)
export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES

# Stop it for all bash shells (may hide problems)
echo "export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES" >> ~/.bashrc

# Stop it for all zsh shells (may hide problems)
echo "export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES" >> ~/.zshrc
```

**IMPORTANT:** This will only work on MacOS High Sierra. This workaround was
removed in the next version [MacOS
Mojave](https://en.wikipedia.org/wiki/MacOS_Mojave).

Like most developers, you are working with a newer MacOS version and need
another workaround or fix to tackle this problem in the long run. Keep on
reading.

## Stop Spring from starting

If you check the
[README](https://github.com/rails/spring#temporarily-disabling-spring) of the
spring project, you will find the environment variable you have to stop, to stop
spring from starting.

```sh
# Start rails web server without spring:
DISABLE_SPRING=true bin/rails s

# define it in the current shell
export DISABLE_SPRING=true
```

I would not disable spring for the whole machine by defining this variable in
the used shell rc file like `.bashrc` or `.zshrc` (according to the shell you
use).

## Removing Spring gem from your project

As spring causes quite some problems, which were never fully solved and due to
the performance increase of current computer systems, many projects can remove
spring - even in legacy projects, where there are many other more important
things to solve.

The [README](https://github.com/rails/spring#removal) of spring has a chapter
describing what you have to do, to remove it from a [Ruby on
Rails](https://rubyonrails.org) project like:

```sh
# remove spring integration in bin/* scripts
bin/spring binstub --remove --all
# stop spring process
bin/spring stop
```

Remove spring from your `Gemfile` and run `bundle install` afterwards:

```diff

 group :development do
-  gem "spring"
-  gem "spring-commands-rspec"
   gem "web-console"
 end
 ```

As many projects were using spring heavily for improving the runtime of the test
suite on developer machines. Check your [rspec](https://rubygems.org/gems/rspec)
setup in `spec/spec_helper.rb`, `spec/rails_helper.rb`. For a
[minitest](https://github.com/minitest/minitest)-based test suite check
`test/test_helper.rb`.

If you are using [guard](https://rubygems.org/gems/guard) check your
`Guardfile` for entries like:

```diff
-guard :rspec, cmd: 'spring rspec -f doc ' do
+guard :rspec, cmd: 'rspec -f doc ' do
```

## Summary

Working with legacy applications is hard and will become even harder over time.
Changes in third-party libraries, OS (operation system), etc. are typical
challenges for many projects.
