Plugin development: A copy of ApplicationController has been removed from the module tree but is still active!

I get this error non-stop when developing. It used to only happen after around ~8 pages, but now it’s happening after around 1-3. The error looks like this:

The blurred text is the name of the module for my plugin

Note how the name is, confusingly (and by my design), ApplicationsController. This shouldn’t be important since I’ve been having this issue long before this controller existed.

I believe this is related to rails code reloading, and shouldn’t have to do with your naming. Something like the following happens:

  • You start the app
  • It loads up the core .rb files and stores the resultant classes into constants (like ApplicationController)
  • Those classes refer to other classes, which are then loaded into constants in the same way (like BaseController if you have ApplicationsController < BaseController)
  • These classes are singletons, meaning only one of them exists in the world, and are uniquely referred to by their class name. Rails keeps track of which constants you’ve defined and loads them automatically when you reference them.

Rails also automatically re-defines most of these constants when you change things. So, if you change the code for BaseController, rails will automatically determine that constant is stale, refresh the definition from your code, as well as any classes referencing that file (so, ApplicationsController will be reloaded as well to account for the new reference to BaseController)

This works great, until you are dealing with classes which are not hot reloaded. A common example with a typical rails app is putting things into the lib directory (rather than the app directory), which are not automatically reloaded by default. So this situation arises when you have a file in /lib which references a file in /app, the /app file is changed, but the /lib file is not, leaving it pointing to a class which has been removed from the list of classes defined in the rails app.

I’ve run into this as well very occasionally with Discourse in the past, but didn’t have the gumption to troubleshoot it too hard. But, as a start, I believe you have a case where some of your plugin code is not being reloaded (maybe something needs to be added to autoload_paths?), and is breaking when it references some constant which is hot reloaded.

Thanks a lot for the response.

None of my Ruby backend code has ever restarted when I made a change, so I suspect you’re right. I also don’t think this happens when I turn cache_classes to true. I’ll see if adding it to autoload_paths fixes it, thanks!

이 문제를 해결하신 적이 있으신가요?

Zeitwerk로 마이그레이션을 완료했으므로 더 이상 이런 일이 발생하지 않아야 합니다. 여전히 발생하고 있다면 정확한 재현 단계를 알려주시겠습니까?

Docker에서 개발 환경으로 Discourse의 stable 브랜치를 커스텀 플러그인과 함께 실행 중입니다. 페이지를 몇 번 새로고침하면 이 문제가 발생하고, 이후에는 서버를 재시작해야 합니다.

아하, 다음 달에 새로운 안정 버전이 출시될 예정입니다. 현재 상태는 매우 일시적인 것이며, 작동은 하지만 다소 번거로운 우회 방법이 있습니다.