1

We recently updated the ruby and rubygems versions of our app, and we've been consistently getting the following error:

A TypeError occurred in [model]#[view]:

String can't be coerced into Integer
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `+'

Here is the backtrace:

vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `+'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `sum'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:92:in `source_extract'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_view/template/error.rb:112:in `annoted_source_code'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:68:in `block in log_error'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/deprecation/reporting.rb:20:in `silence'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:66:in `log_error'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:34:in `render_exception'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/debug_exceptions.rb:27:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/exception_notification-4.1.1/lib/exception_notification/rack.rb:32:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/show_exceptions.rb:56:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:32:in `call_app'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:16:in `block in call'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/tagged_logging.rb:22:in `tagged'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/rack/logger.rb:16:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/request_id.rb:22:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/methodoverride.rb:21:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/runtime.rb:17:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/activesupport-3.2.22.5/lib/active_support/cache/strategy/local_cache.rb:72:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/lock.rb:15:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-1.4.7/lib/rack/deflater.rb:13:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/actionpack-3.2.22.5/lib/action_dispatch/middleware/static.rb:83:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-ssl-1.3.4/lib/rack/ssl.rb:27:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:140:in `forward'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:249:in `fetch'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:189:in `lookup'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:66:in `call!'
vendor/bundle/ruby/2.5.0/gems/rack-cache-1.7.2/lib/rack/cache/context.rb:51:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
lib/rack/assets.rb:167:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
lib/rack/basics.rb:24:in `call'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/engine.rb:484:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/application.rb:231:in `call'
vendor/bundle/ruby/2.5.0/gems/railties-3.2.22.5/lib/rails/railtie/configurable.rb:30:in `method_missing'
vendor/bundle/ruby/2.5.0/gems/newrelic_rpm-5.1.0.344/lib/new_relic/agent/instrumentation/middleware_tracing.rb:92:in `call'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:606:in `process_client'
config/unicorn.rb:94:in `process_client_with_gc'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:701:in `worker_loop'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:549:in `spawn_missing_workers'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/lib/unicorn/http_server.rb:142:in `start'
vendor/bundle/ruby/2.5.0/gems/unicorn-5.4.0/bin/unicorn:126:in `<top (required)>'
vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `load'
vendor/bundle/ruby/2.5.0/bin/unicorn:23:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:75:in `kernel_load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli/exec.rb:28:in `run'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:424:in `exec'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/command.rb:27:in `run'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/invocation.rb:126:in `invoke_command'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor.rb:387:in `dispatch'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:27:in `dispatch'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/vendor/thor/lib/thor/base.rb:466:in `start'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/cli.rb:18:in `start'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/exe/bundle:30:in `block in <top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/lib/bundler/friendly_errors.rb:122:in `with_friendly_errors'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/gems/bundler-1.16.1/exe/bundle:22:in `<top (required)>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/bundle:23:in `load'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/bundle:23:in `<main>'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/ruby_executable_hooks:15:in `eval'
/usr/local/rvm/gems/ruby-2.5.1-tagX4gpqkt9tzqft/bin/ruby_executable_hooks:15:in `<main>'

I'm trying to understand why this error is happening. Based on the backtrace it doesn't seem to be caused by our code, and since it only happens on some pages of the site I don't think that its a gem compatibility issue. Of note is that the ActionView::Template::Error code is calling sum on an array of strings:

79  def source_extract(indentation = 0)
80    return unless num = line_number
81    num = num.to_i
82
83    source_code = @template.source.split("\n")
84
85    start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
86    end_on_line   = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
87
88    indent = ' ' * indentation
89    line_counter = start_on_line
90    return unless source_code = source_code[start_on_line..end_on_line]
91
92    source_code.sum do |line|
93      line_counter += 1
94      "#{indent}#{line_counter}: #{line}\n"
95    end
96  end

but that does seem to be a valid use of the Array#sum method (https://ruby-doc.org/core-2.5.1/Array.html#method-i-sum). Is this something wrong with our codebase or is there an error in the ActionPack gem?

Here is the relevant except from our config/unicorn.rb:

93  def process_client_with_gc(client)
94    res = process_client_without_gc(client)
95    possibly_run_gc
96    res
97  end
98
99  alias_method :process_client_without_gc, :process_client
100 alias_method :process_client, :process_client_with_gc
Tim Maher
  • 11
  • 2
  • 1
    What about this line? `config/unicorn.rb:94:in `process_client_with_gc'` – Kartikey Tanna Jun 01 '18 at 14:48
  • Added some info about that to the post. To explain, 'process_client_with_gc' just calls Unicorn's 'process_client' and then runs the garbage collector if a large number of clients have already been processed (thats 'possibly_run_gc', just a counter with a fudge factor). – Tim Maher Jun 01 '18 at 15:20
  • Tim there seems to be some slight confusion here. Since you are using ruby >= 2.4 which supports `Enumerable#sum` as part of core but you are using rails 3.2 which implements [`Enumerable#sum`](https://apidock.com/rails/v3.2.3/Enumerable/sum) in a different manner (e.g `enum.inject(:+)`). I am not sure why the core implementation is taking precedence over the rails version (as I would have assumed the opposite) but herein lies your issue. – engineersmnky Jun 01 '18 at 15:32
  • Recommendations: 1) upgrade rails version, which can be time consuming and potentially difficult given the potential version jumps required 2) downgrade ruby version much easier since you only need to drop back to 2.3. The reason for the intermittent behavior is that this is actually occuring when there is another error and action_view is trying to show you the error but that causes an error of its own in the process. – engineersmnky Jun 01 '18 at 15:33
  • Chances are your actual error is occurring in `process_client_with_gc` or `lib/rack/*.rb` – engineersmnky Jun 01 '18 at 15:45
  • You're using Ruby `2.5` and Rails `3.2`. That's your problem. You need to upgrade rails before you can upgrade ruby that far. – Tom Lord Jun 01 '18 at 15:54
  • @TomLord https://rubygems.org/gems/rails/versions/3.2.22.5 lists rails 3.2.22.5 as requiring ruby >= 1.8.7. If that info is wrong could you let me know where to find correct information? I'm working on testing the suggestion of downgrading to ruby 2.3 now but I'd like to avoid this mistake in the future. – Tim Maher Jun 01 '18 at 16:52

1 Answers1

0

Credit to engineersmnky and Tom Lord for their solutions.

The issue was that ruby >= 2.4 supports Enumerable#sum as part of core, but rails 3.2 also implements Enumerable#sum. These two implementations are different. It seems like the core implementation is taking precedence over the rails version and that causes the error above.

The solutions:

  1. Upgrade the rails version, which can be time consuming and potentially difficult given the potential version jumps required
  2. Downgrade the ruby version. This was much easier for me as I only needed to drop back to 2.3.
Tim Maher
  • 11
  • 2
  • Ruby 2.4 support was [added to Rails `4.2.8`](https://weblog.rubyonrails.org/2017/2/11/this-week-in-rails-ruby-2-4-on-rails-4-2/). It will not work with older versions of rails. – Tom Lord Jun 03 '18 at 19:35
  • You are right that, for example, Rails 3.2 does not specify a maximum ruby version - but that's because it was compatible with the latest ruby at the time, and could not predict the future of the language! Rails 3.2.22 was released on June 16, 2015; Ruby 2.4 was released on December 25, 2016. – Tom Lord Jun 03 '18 at 19:37
  • Your "solution" to downgrade ruby is valid, but it's worth noting that rails 3 has reached end-of-life; there are no more security patches, and many libraries have dropped support for it. So for any "serious" project, it's important to upgrade as soon as possible. – Tom Lord Jun 03 '18 at 19:40