Rails 7.0.8.1 app not loading due to "NameError: uninitialized constant WickedPdf::OpenStruct"

Hi there y’all. :wave:

I had an interesting issue upgrading a Rails app from 6.1 to 7.0 and I am trying to find a way to figure out where is the root cause.

Here is a glimpse:

  • It just works: with Rails 6.1, zeitwerk enabled, Ruby 3.1.4, wickedPdf v2.8.0
  • It breaks: with Rails 7.0.8.1, Ruby 3.1.4, wickedPdf v2.8.0

What I mean by “It just works” is: pdf generation works in Dev, Staging, CI, and Production, and the app loads correctly.

And by “it breaks”: the app doesn’t load in production and spits out:

NameError: uninitialized constant WickedPdf::OpenStruct

BTW: This is a 9 1/2 monolith Rails app running on Heroku.

There is a disparity between Staging/Dev/CI and Prod (although staging.rb and production.rb are 99% identical) that causes this to fail only in Production, but I am suspecting there is something else causing this issue.

I am not sure if this a weird Rails 7.0 autoloading edge case, or Zeitwerk, or WickedPDF referring to “OpenStruct” instead of “::OpenStruct” (or maybe even missing ostruct in WickedPdf gemspec).

I found a work around and Rails 7.0 is in production already, and I am now trying to figure out what is the exact problem.

Has anybody run into something like that?!

BTW: the solution that worked for me and this particular Rails app was to add require 'ostruct' to application.rb.

And, the next version of WickedPDF will have this problem fixed: fix: OpenStruct causes NameError in Rake13.2.0 by rhiroe · Pull Request #1110 · mileszs/wicked_pdf · GitHub

Yeah, this is unrelated to autoloading, the Rails autoloaders do not manage external dependencies, only application/engines autoload paths.

That library depended on ostruct, but since some dependency was loading it, the missing require call was overlooked.

1 Like