Once again production deploying a rails app which is exciting. This time a Rails 7.1 app following the same guide I have before by Ralf Ebert Ruby on Rails – Deployment Tutorial. My setup is all good for rails 7.1, and the app is deployed and nginx configured for saxshop.sebastiandetering.com.
Unfortunately I'm getting a 500 error from unicorn that I haven't seen before. It seems to be an issue with a payload containing some session headers unicorn cannot parse. Here's my log from /home/saxshop/app/shared/log/unicorn.log:
`I, [2024-06-05T02:32:21.616740 #1197755] INFO -- : [734c58b0-4118-4545-9f5d-1f40a86e5041] Started GET "/" for 2603:8000:6000:ccc1:1911:39ec:3317:d4d1 at 2024-06-05 02:32:21 +0000 I, [2024-06-05T02:32:21.617954 #1197755] INFO -- : [734c58b0-4118-4545-9f5d-1f40a86e5041] Processing by SiteController#home as HTML I, [2024-06-05T02:32:21.624858 #1197755] INFO -- : [734c58b0-4118-4545-9f5d-1f40a86e5041] Rendered layout layouts/application.html.erb (Duration: 4.3ms | Allocations: 1581) I, [2024-06-05T02:32:21.625212 #1197755] INFO -- : [734c58b0-4118-4545-9f5d-1f40a86e5041] Completed 200 OK in 7ms (Views: 4.2ms | ActiveRecord: 1.2ms | Allocations: 1919) E, [2024-06-05T02:32:21.626527 #1197755] ERROR -- : app error: undefined method`=\~' for \["\_saxshop_session=5hMztV6NPXd8pLw61KN9JHz%2FFUwV%2BEOoP%2B62bT6ghI18rMIL1mbUc1dzAofXs1dMT5PnWMNi8EDy9nSMNqr3FM88P2PJgn0EKNdTASj0FyPvZTyqZymyo3ApBdcowBsfEobINQCEKj3iPbmcR97%2BaabxUrPKTBq5rSDHbv9HgxU7qsg1CO%2BL7N7%2FiT1b3JaNIhoZmP%2Bd8Q%2F%2BpVGzMypYpdsoIoB8YCaDPc9ENxVFwTO4fU07RA9ZcXnE7BsdnvAINoSTLVLCcM721ZtluSYmOCoZNoNW3DLz--ORfA6Q3dY%2B05TYTF--9a1sTAkoez2smjWXZiiM4A%3D%3D; path=/; secure; httponly; SameSite=Lax"\]:Array (NoMethodError)
E, \[2024-06-05T02:32:21.626628 #1197755\] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_response.rb:43:in `block in http_response_write' E, [2024-06-05T02:32:21.626654 #1197755] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_response.rb:34:in `each'
E, \[2024-06-05T02:32:21.626684 #1197755\] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_response.rb:34:in `http_response_write' E, [2024-06-05T02:32:21.626705 #1197755] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_server.rb:645:in `process_client'
E, \[2024-06-05T02:32:21.626722 #1197755\] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_server.rb:739:in `worker_loop' E, [2024-06-05T02:32:21.626739 #1197755] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_server.rb:547:in `spawn_missing_workers'
E, \[2024-06-05T02:32:21.626757 #1197755\] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/lib/unicorn/http_server.rb:143:in `start' E, [2024-06-05T02:32:21.626774 #1197755] ERROR -- : /home/saxshop/app/shared/vendor/bundle/ruby/3.2.0/gems/unicorn-6.1.0/bin/unicorn:128:in `\<top (required)\>'
E, \[2024-06-05T02:32:21.626791 #1197755\] ERROR -- : /home/saxshop/app/releases/5/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `load' E, [2024-06-05T02:32:21.626809 #1197755] ERROR -- : /home/saxshop/app/releases/5/vendor/bundle/ruby/3.2.0/bin/unicorn:25:in `\<main\>'
E, \[2024-06-05T02:32:21.626830 #1197755\] ERROR -- : /usr/local/rvm/gems/ruby-3.2.0/bin/ruby_executable_hooks:22:in `eval' E, [2024-06-05T02:32:21.626851 #1197755] ERROR -- : /usr/local/rvm/gems/ruby-3.2.0/bin/ruby_executable_hooks:22:in `\<main\>'
\`
Any unicorn users know what might be up?
Here's where in the unicorn github this error is hitting https://github.com/Shopify/unicorn/blob/master/lib/unicorn/http_response.rb line 43
source code for my ruby on rails app: https://github.com/TimeTravelerFromNow/saxshop
So far I've been debugging and got to this point after a javascript.css not found in asset pipeline error. Dont think that is related. I might try editing the unicorn source code and seeing what happens. The app works on local no issues. In the Gemfile, I also moved the sqlite gem into development group.
Stack Overflow Recommendations I've tried: Unicorn + Rails 7.1: TypeError: wrong argument type strio (expected strio) (TypeError)
Rack 3 is unsupported by unicorn 6.1.0
Rack 3 uses arrays in response headers now, which unicorn does not yet handle. Adding a case for an Array fixed my problem.
Solution
In the unicorn gem lib/unicorn/http_response.rb change the code in your gem source line 43 in the else:
case value
when Array # Rack 3
value.each { |v| buf << "#{key}: #{v}\r\n" }
when /\n/ # Rack 2
# avoiding blank, key-only cookies with /\n+/
value.split(/\n+/).each { |v| buf << "#{key}: #{v}\r\n" }
else
buf << "#{key}: #{value}\r\n"
end
Keep Unicorn Up To Date!
On github, user jeremyevans shared that Rack 3 is supported in upstream unicorn but is pending release (of writing this Jun 7 2024). the next unicorn version will include the fix
Unicorn patch that supports Rack 3 https://yhbt.net/unicorn.git/9d7bab0bc2211b20806d4d0289a7ea992e49a8a1/s/