chocolatedonut

chocolatedonut

Plug.Conn.__struct__/0 is undefined

:appsignal_plug, a dependency of :appsignal_phoenix, fails on this line, with an error Plug.Conn.__struct__/0 is undefined.

Any idea on what might be causing this, and how to fix it, appreciated. :pray:

What I’ve tried so far:

  • rm -rf _build deps
  • mv ~/.hex/cache.ets ~/.hex/cache.ets.bak
  • locally cloned and successfully compiled :appsignal_plug ( {:appsignal_plug, path: "/appsignal-elixir-plug", override: true})
  • removed :appsignal_* deps, but now :bandit reports same error (module Plug.Conn is not loaded and could not be found).

Full error from mix deps.compile output:

==> appsignal
AppSignal extension installation successful
Compiling 54 files (.ex)
Generated appsignal app
==> appsignal_plug
Compiling 2 files (.ex)
     error: Plug.Conn.__struct__/0 is undefined, cannot expand struct Plug.Conn. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
     │
 100 │   def put_name(%Plug.Conn{} = conn, name) do
     │                ^
     │
     └─ lib/appsignal_plug.ex:100:16: Appsignal.Plug.put_name/2

    error: Plug.Conn.__struct__/0 is undefined, cannot expand struct Plug.Conn. Make sure the struct name is correct. If the struct name exists and is correct but it still cannot be found, you likely have cyclic module usage in your code
    │
  3 │         %Plug.Conn{
    │         ^
    │
    └─ lib/appsignal_plug/metadata.ex:3:9: Appsignal.Metadata.Plug.Conn.metadata/1


== Compilation error in file lib/appsignal_plug.ex ==
** (CompileError) lib/appsignal_plug.ex: cannot compile module Appsignal.Plug (errors have been logged)
    lib/appsignal_plug.ex:100: (module)
could not compile dependency :appsignal_plug, "mix compile" failed. Errors may have been logged above. You can recompile this dependency with "mix deps.compile appsignal_plug --force", update it with "mix deps.update appsignal_plug" or clean it with "mix deps.clean appsignal_plug"

Odd things noticed:

  • the above error occurs even when referring to a locally-cloned :appsignal_plug ({:appsignal_plug, path: "/appsignal-elixir-plug"}) … even though that locally-cloned repo compiles!
  • :appsignal_plug compiles in another, older instance of my application, on the same server. The problematic application’s mix.lock is identical to the older one’s, regarding the 3 AppSignal libs. Both mix.locks have this:
  "appsignal": {:hex, :appsignal, "2.12.2", "f93bed975c73779e1711fb2196b4c340c50b474ab41a7026e8599b0b4b5db046", [:make, :mix], [{:decimal, "~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:decorator, "~> 1.2.3 or ~> 1.3", [hex: :decorator, repo: "hexpm", optional: false]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c4063fcd264a5e372299bec15bbf35a057ae5912c739d374616e0a33c0cc9ef0"},
  "appsignal_phoenix": {:hex, :appsignal_phoenix, "2.4.0", "150cf8753e3f0a6352504886808c822a4b8099afdfb4b8ff98cbd8d49c99663d", [:mix], [{:appsignal, ">= 2.11.0 and < 3.0.0", [hex: :appsignal, repo: "hexpm", optional: false]}, {:appsignal_plug, ">= 2.0.15 and < 3.0.0", [hex: :appsignal_plug, repo: "hexpm", optional: false]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11 or ~> 3.0 or ~> 4.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.9 or ~> 1.0", [hex: :phoenix_live_view, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "2808cbf12c0ab16ae909ccbae1af758d7478e6165a4324277f701bafbcf70aa1"},
  "appsignal_plug": {:hex, :appsignal_plug, "2.0.15", "758a8a78944878e8461bbc77ca86219121a56f4299c6d79940ab083cf9afea00", [:mix], [{:appsignal, ">= 2.7.6 and < 3.0.0", [hex: :appsignal, repo: "hexpm", optional: false]}, {:plug, ">= 1.1.0", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "1c6059049e2081e808aaef04e2b9917e06277f61a35a0e103db860d08cbc41f1"}
  • I checked the 2 myapp versions for any difference in Plug usage, but grep Plug /myapp{newer,older}/lib/**/*.ex output is identical.

Env

Elixir 1.17.1
Erlang 27.0
Ubuntu 20.04.6

Marked As Solved

chocolatedonut

chocolatedonut

Thanks. I already tried both. (Even though the rm cmd in OP had incorrect/reversed dir names – it should be rm -rf _build deps – I did do rm against correct dirs.)

I now realised that mix.exs still had a :plug reference to a :path from a local computer, but which doesn’t exist on the server:

{:plug, path: "/local-dev/plug", override: true, only: :dev}

Removing the above fixed the issue. :tada:

But can you advise how to avoid such issue in the future? Why did…

  1. mix deps.get --only prod
  2. mix deps.compile

…keep “silently” failing? “silently” as in not pointing to the actual cause of the issue (if this was indeed the “root” cause). mix deps.get without the --only prod flag does warn that the above :plug :path doesn’t exist.

In mix.lock all :plug references seemed to be referring to "hexpm", even with the above {:plug, ..., only: :dev}. F.e. ref for "phoenix" in mix.lock:

{:plug, "~> 1.14", [hex: :plug, repo: "hexpm", optional: false]

If it matters, MIX_ENV was set to prod throughout.

What could I’ve done better?

Where Next?

Popular in Questions Top

vonH
When I run the Plug and I recompile I wind up having to use Ctrl C to quit iex and start again. Witht the help of rlwrap I can use the cu...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
ashish173
I am using Ecto timestamps with postgres, I can see the timestamps() use the :naive_dateime but for my use case I wanted to store the ti...
New
Fl4m3Ph03n1x
About me? ( if you have nothing better to do than reading about some random guy in the internet :stuck_out_tongue: ) Hello all, this is ...
New
pmjoe
I have a relationship of love and hate with Elixir. Lots of things are just absolutely right, but there are some things that are kind of ...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New
sorentwo
Hello! tl;dr Announcing Oban, an Ecto based job processing library with a focus on reliability and historical observability. After spen...
985 44778 311
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
albydarned
Hello all! I am typing this post from my new MacBook Pro with the M1 chip. I’m loving it so far, and will probably use it as my daily dr...
New
sergio
Kind of like when jquery came out, it was super necessary. Existing drag and drop libraries have a bunch of baggage to support old browse...
New

We're in Beta

About us Mission Statement