** (ArgumentError) no “group_without_children” html template defined for SctWeb.FdGroupHTML (the module exists but does define group_without_children/1 nor render/2)
I have tried a number of troubleshooting steps:
Check that the embed_templates is correct in the _view file.
Check the name of the template is “group_without_children.html.heex”
Check that it is in the folder and is in the right folder.
rerun tests - still fails
So I backtracked and realized that I actually originally made the file elsewhere and had dragged it into the fd_group_html folder afterwards.
So I tried creating a HEEX template in another folder and added an action that referenced it, and a test for that action. Ran the test and the test of course failed since I have not moved the HEEX template into the correct folder. So now I move the template into the correct folder and rerun the test. Still fails with error like above - the module exists but does not define the template as a 1 arity function. Did all the double checks again (name is correct, folder is correct).
But when I ran “mix test” after moving the template into the proper folder I realized I saw no compiles occur??? Wait… should it not have to recompile the view module with the embed_templates again?
So I made a small change to the view templates module file (added a space before a parameter.
Ran the tests again and this time it compiled 1 .ex - guess what THIS time it discovered the HEEX template.
So my question is what triggers a view module to recompile if you add a new template to the folder referenced in the embed_templates wildcard?
Note: Since I have been doing this for 6 months now and now this is happening I infer it may be related to the Elixir 1.15 compilation optimizations and is not truly a Phoenix issue. Would like to know either way. And if there is some other process I need to go through to announce HEY there is a new template would also like to know.
I appear to be able to reproduce it. I have NOT tried it with Elixir 1.15.2 nor on OTP 26. But I will reproduce it tomorrow WTP twice to ensure I understand the minimal steps to reproduction.
Perhaps it would be helpful if I knew where in the code this should trigger automatically? I would enjoy looking at that code.
I am wondering if this requires that live_reload in config of the endpoint needs to be on for this to recompile. I have that turned off presently, so am going to see if that has anything to do with this detection. It does not seem to be required for running tests of template changes, but it may be for template “additions”.
No - I only had live_reload off in dev and I am running the tests in test env. I was able to reproduce it by merely creating a new template in the folder and then referencing it from an existing action. SO only change was a new template file in the folder and a change to the controller action. I must be missing something.
Is “another folder” still in the same Mix project? Could it be the compiler somehow “seeing” the Heex file at the old location and then not notice when it moves?
Also, what operating system are you on? I’m not sure if it’s related, but I’ve burned too much time chasing “this only happens on Windows with antivirus” bugs to not double-check.
Yes - same mix project, but I am not doing anything in between to invoke compilation. And I am on MacOS. I am using VS code as IDE, but I also tried same sequence through iterm outside vscode to no avail.
Was able to reproduce on Elixir 1.15.2. Same steps:
Create a new HEEX template in folder already referenced in view module.
Change or add a controller action to refer to new template name.
Run mix test that smoke tests that action
Result is it recompiles 4 files (in my case) and runs test and fails:
** (ArgumentError) no "copy" html template defined for SctWeb.FdGroupHTML (the module exists but does define copy/1 nor render/2)
Make slight change to view module (added a space embed_templates( "fd_group_html/*") )
Run mix test
Result is it compiles 1 module (I infer the view module just changed) and it finds the new template.
In itself this is a very low priority issue with an easy workaround. I am here to help try things though in the interest in determining root cause (my fault or otherwise) . Here to help. I am still uncertain if this is a Elixir issue or a Phoenix issue or a Phoenix template issue.
When I upgraded to Elixir 1.15.2 I noticed that my NimblePublisher resources weren’t picking up new files when compiling for prod. Didn’t notice during the dev env because I think Phoenix code_reloader catches the changes. Only when I updated the module that uses NimblePublisher, forcing a recompile in the prod environment, did the rest of the new pages pick up.
I think the key here is the environment change, which doesn’t have Phoenix code_reloader. My issue bubbled up in prod while yours was in test.
I’ve put together a reproduction here:
Running load_in_file.exs and then running mix compile shows that the __mix_recompile__? isn’t firing despite the new file added to content/pages/
A demonstration
~/repos/recompile main
❯ mix compile
~/repos/recompile main
❯ elixir load_in_file.exs
title6520251
~/repos/recompile main*
❯ mix compile
~/repos/recompile main*
❯ iex -S mix phx.server
[info] Running RecompileWeb.Endpoint with cowboy 2.10.0 at 127.0.0.1:4000 (http)
[info] Access RecompileWeb.Endpoint at http://localhost:4000
Erlang/OTP 26 [erts-14.0.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
[watch] build finished, watching for changes...
Interactive Elixir (1.15.2) - press Ctrl+C to exit (type h() ENTER for help)
Rebuilding...
Done in 148ms.
iex(1)> Recompile.Content.list_pages()
[
%Recompile.Content.Page{title: "another", body: "<p>\ntest again</p>\n"},
%Recompile.Content.Page{title: "the title", body: "<p>\ntesting this</p>\n"}
]
iex(2)>