Trouble with Zeitwerk reloading

An apparently new test has identified a problem that I think I might have known I had, but had always ignored. Now I can’t ignore it because it now makes the tests fail. Here are my routes:

# frozen_string_literal: true
require_dependency "pfaffmanager_constraint"

Pfaffmanager::Engine.routes.draw do
  get "/" => "pfaffmanager#index", :constraints =>
  get "/servers" => "servers#index", :constraints =>
  #      get "#{root_path}/:username/messages/group/:group_name" => "user_actions#private_messages", constraints: { username: RouteFormat.username, group_name: RouteFormat.username }
  get "/servers/group/:group_name" => "servers#index",
      :constraints =>
  get "/find/:s" => "servers#index", :constraints =>
  get "/group/:group_name" => "servers#index",
      :constraints =>
  get "/inventory/:group_name.json" => "servers#inventory",
      :constraints =>
  get "/servers/:id" => "servers#show",
      :constraints =>
  get "/servers/:id/edit" => "servers#edit",
      :constraints =>
  put "/servers/:id" => "servers#update",
      :constraints =>
  delete "/servers/:id" => "servers#delete",
         :constraints =>
  put "/status/:id" => "servers#update_status",
      :constraints =>
  post "/api_key/:id" => "servers#set_api_key",
       :constraints =>
  put "/update_server_status/:id" => "servers#update_server_status",
      :constraints =>
  post "/upgrade/:id" => "servers#queue_upgrade",
       :constraints =>
  put "/install/:id" => "servers#install",
      :constraints =>
  get "/ssh_key/:id" => "serverkeys#get_pub_key"
  get "/ssh-key/:hostname" => "serverkeys#get_pub_key_by_hostname",
      :constraints => {
        hostname: %r{[^/]+}
  post "/servers" => "servers#create",
       :constraints =>

Discourse::Application.routes.append do
  mount ::Pfaffmanager::Engine, at: "/pfaffmanager"

And it fails like this:

/home/pfaffman/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/routing/route_set.rb:588:in `add_route': Invalid route name, already in use: 'pfaffmana
ger'  (ArgumentError)                                                                                                                                                                         
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restri
ct the routes created with `resources` as explained here:                                                                                                                                                                                                                                                
          raise ArgumentError, "Invalid route name, already in use: '#{name}' \n" \                                                                                                           
        from /home/pfaffman/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/routing/mapper.rb:1985:in `add_route'   
        from /home/pfaffman/.asdf/installs/ruby/3.2.2/lib/ruby/gems/3.2.0/gems/actionpack-7.0.7/lib/action_dispatch/routing/mapper.rb:1956:in `decomposed_match'  

Have you seen this topic? If you follow the structure there (and in the plugin-skeleton), things should work pretty smoothly:

An important part of Zeitwerk autoloading is the file names/paths, so it’s hard to identify the problem from the snippet you shared. Is that in a plugin.rb file? Or some other file?


Sorry. That’s config/routes.rb

But I also have . . . stuff . . . in lib/discourse-pfaffmanager/engine.rb, so maybe I need to move the stuff from routes.rb into lib/pfaffmanager/engine.rb. RTFM some more.

1 Like

I think you probably need to make this change:

- Discourse::Application.routes.append do
+ Discourse::Application.routes.draw do

That way, the file can be ‘reloaded’ multiple times without causing a clash. (‘draw’ will replace any existing route, while ‘append’ will raise an error if there is a clash)

That would also make it match the current plugin-skeleton:


That did it!

Always so obvious when it’s figured out.

Thanks a zillion.

(Now if I could just get vscode to do the linting when files save, but at least it’s now happening locally before it goes to github. . . )

1 Like

Yep, that’s exactly a change I made recently.


That does make me feel a bit better. . .

But did it take you 4 hours? :crying_cat_face:

Thanks again, David. I really appreciate your support.


Not on this occasion, sometimes you get lucky ;). On this occasion I happened to read Davids guide and took note of that difference to the code that I had originally been following.

But sure, some issues take a walk in the local park on the following day to fix :deciduous_tree:

1 Like

FWIW, if I post a guide about something it’s generally because I lost many hours/days trying to figure it out myself :sweat_smile:. All this Zeitwerk stuff definitely falls into that category!

:100: :chefs_kiss:

So noted. I do eat all of them when you post. I should have searched just for zeitwork and maybe I’d have found it. But even then, the issue was literally just one word that seemed so innocuous.

Now I’m trying to make all of my {{blah... stuff into <blah... . It’s killing me. But I think I understand it (well enough to do it in maybe a few more days).


This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.