Dialyzer/dialyxir suddenly failing

Hi,

I have an umbrella project containing two applications (one Phoenix, one plain Elixir), with dialyxir configured in the umbrella. It all worked fine until recently, when suddenly mix dialyzer started failing (see below for output). My problem is I can’t work out what changed to cause the failures – I’ve reverted to a version where I’m certain it used to work, and still get the same errors, so I assume it’s something external to the project. I’ve also tried removing the _build directory, and even ~/.mix, and in increasing desperation even reinstalling elixir and erlang, but nothing has helped so far.

I’m hoping someone can at least point me in the right direction to start looking for a solution, as I’m completely stumped (I’m a relative newcomer to the platform).

I’m using Elixir 1.4.0 on Erlang 19, and dialyxir 0.5.0, running on Mac OS 10.12.4. Here’s the output I get:

mix dialyzer --halt-exit-status
Checking PLT...
[:asn1, :certifi, :combine, :compiler, :cowboy, :cowlib, :crypto, :eex, :elixir,
 :fs, :gettext, :hackney, :httpoison, :idna, :kernel, :logger, :metrics, :mime,
 :mimerl, :oauth2, :phoenix, :phoenix_html, :phoenix_live_reload,
 :phoenix_pubsub, :phoenix_slime, :plug, :poison, :public_key, :ranch, :slime,
 :ssl, :ssl_verify_fun, :stdlib, :strava, :timex, :tzdata, :ytd_core]
PLT is up to date!
Starting Dialyzer
dialyzer args: [check_plt: false,
 init_plt: '/Users/kerry/dev/ytd/_build/dev/dialyxir_erlang-19.3_elixir-1.4.0_deps-dev.plt',
 files_rec: ['/Users/kerry/dev/ytd/_build/dev/lib/ytd_web/ebin',
  '/Users/kerry/dev/ytd/_build/dev/lib/ytd_core/ebin'], warnings: [:unknown]]
done in 0m2.15s
:0: Unknown function 'Elixir.Gettext':dgettext/4
:0: Unknown function 'Elixir.Gettext':dngettext/6
:0: Unknown function 'Elixir.Gettext.Compiler':expand_to_binary/4
:0: Unknown function 'Elixir.Gettext.Compiler':warn_if_domain_contains_slashes/1
:0: Unknown function 'Elixir.Gettext.Extractor':extract/4
:0: Unknown function 'Elixir.Gettext.Extractor':'extracting?'/0
:0: Unknown function 'Elixir.Gettext.Interpolation':interpolate/2
:0: Unknown function 'Elixir.Gettext.Interpolation':to_interpolatable/1
:0: Unknown function 'Elixir.Logger':bare_log/3
:0: Unknown function 'Elixir.Phoenix.Channel.Server':broadcast/4
:0: Unknown function 'Elixir.Phoenix.Channel.Server':'broadcast!'/4
:0: Unknown function 'Elixir.Phoenix.Channel.Server':broadcast_from/5
:0: Unknown function 'Elixir.Phoenix.Channel.Server':'broadcast_from!'/5
:0: Unknown function 'Elixir.Phoenix.CodeReloader':call/2
:0: Unknown function 'Elixir.Phoenix.CodeReloader':'reload!'/1
:0: Unknown function 'Elixir.Phoenix.Config':cache/3
:0: Unknown function 'Elixir.Phoenix.Controller':accepts/2
:0: Unknown function 'Elixir.Phoenix.Controller':fetch_flash/2
:0: Unknown function 'Elixir.Phoenix.Controller':protect_from_forgery/2
:0: Unknown function 'Elixir.Phoenix.Controller':put_new_layout/2
:0: Unknown function 'Elixir.Phoenix.Controller':put_new_view/2
:0: Unknown function 'Elixir.Phoenix.Controller':put_secure_browser_headers/2
:0: Unknown function 'Elixir.Phoenix.Controller':redirect/2
:0: Unknown function 'Elixir.Phoenix.Controller':render/2
:0: Unknown function 'Elixir.Phoenix.Controller.Pipeline':'__catch__'/5
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':config_change/3
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':start_link/2
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':static_path/2
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':static_url/1
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':struct_url/1
:0: Unknown function 'Elixir.Phoenix.Endpoint.Adapter':url/1
:0: Unknown function 'Elixir.Phoenix.Endpoint.Instrument':extract_endpoint/1
:0: Unknown function 'Elixir.Phoenix.Endpoint.Instrument':strip_caller/1
:0: Unknown function 'Elixir.Phoenix.Endpoint.RenderErrors':'__catch__'/4
:0: Unknown function 'Elixir.Phoenix.HTML.Engine':fetch_assign/2
:0: Unknown function 'Elixir.Phoenix.HTML.Safe':to_iodata/1
:0: Unknown function 'Elixir.Phoenix.HTML.Tag':content_tag/3
:0: Unknown function 'Elixir.Phoenix.LiveReloader':call/2
:0: Unknown function 'Elixir.Phoenix.Logger':phoenix_channel_join/3
:0: Unknown function 'Elixir.Phoenix.Logger':phoenix_controller_call/3
:0: Unknown function 'Elixir.Phoenix.Param':to_param/1
:0: Unknown function 'Elixir.Phoenix.PubSub':subscribe/3
:0: Unknown function 'Elixir.Phoenix.PubSub':subscribe/4
:0: Unknown function 'Elixir.Phoenix.PubSub':unsubscribe/2
:0: Unknown function 'Elixir.Phoenix.Router':'__bypass__'/3
:0: Unknown function 'Elixir.Phoenix.Router.Helpers':path/3
:0: Unknown function 'Elixir.Phoenix.Router.Helpers':raise_route_error/5
:0: Unknown function 'Elixir.Phoenix.Router.Helpers':url/2
:0: Unknown function 'Elixir.Phoenix.Router.NoRouteError':exception/1
:0: Unknown function 'Elixir.Phoenix.Template':hash/2
:0: Unknown function 'Elixir.Phoenix.Template':raise_template_not_found/3
:0: Unknown function 'Elixir.Phoenix.View':render/3
:0: Unknown function 'Elixir.Plug.Conn':assign/3
:0: Unknown function 'Elixir.Plug.Conn':fetch_session/1
:0: Unknown function 'Elixir.Plug.Conn':fetch_session/2
:0: Unknown function 'Elixir.Plug.Conn':get_session/2
:0: Unknown function 'Elixir.Plug.Conn':put_private/3
:0: Unknown function 'Elixir.Plug.Conn':put_session/3
:0: Unknown function 'Elixir.Plug.Conn.Query':encode/2
:0: Unknown function 'Elixir.Plug.Conn.WrapperError':reraise/3
:0: Unknown function 'Elixir.Plug.Debugger':'__catch__'/4
:0: Unknown function 'Elixir.Plug.HTML':html_escape/1
:0: Unknown function 'Elixir.Plug.Head':call/2
:0: Unknown function 'Elixir.Plug.Logger':call/2
:0: Unknown function 'Elixir.Plug.MethodOverride':call/2
:0: Unknown function 'Elixir.Plug.Parsers':call/2
:0: Unknown function 'Elixir.Plug.RequestId':call/2
:0: Unknown function 'Elixir.Plug.Session':call/2
:0: Unknown function 'Elixir.Plug.Static':call/2
:0: Unknown function 'Elixir.Strava.Athlete':retrieve_current/1
:0: Unknown function 'Elixir.Strava.Athlete':stats/2
:0: Unknown function 'Elixir.Strava.Auth':'authorize_url!'/0
:0: Unknown function 'Elixir.Strava.Auth':'get_token!'/1
:0: Unknown function 'Elixir.Strava.Client':new/1
:0: Unknown function 'Elixir.Timex':day/1
:0: Unknown function 'Elixir.Timex':end_of_week/2
:0: Unknown function 'Elixir.Timex':'is_leap?'/1
lib/phoenix/endpoint.ex:1: Callback info about the 'Elixir.Plug' behaviour is not available
lib/phoenix/router.ex:1: Callback info about the 'Elixir.Plug' behaviour is not available
web/channels/user_socket.ex:1: Callback info about the 'Elixir.Phoenix.Socket' behaviour is not available
web/controllers/auth_controller.ex:1: Callback info about the 'Elixir.Plug' behaviour is not available
web/controllers/index_controller.ex:1: Callback info about the 'Elixir.Plug' behaviour is not available
web/gettext.ex:1: Callback info about the 'Elixir.Gettext.Backend' behaviour is not available
done (warnings were emitted)
make: *** [dialyzer] Error 2

Thanks!

Kerry

I’d start by looking at the output of

dialyzer --plt_info

to determine if it is referencing the correct BEAM files for the identified modules.

If it’s linked to the wrong files it’s probably time to rebuild the Persistent Lookup Table (PLT).

I gather mix dialyzer --plt doesn’t do anything?

Hmm. Looks like mix dialyzer --plt creates three files:

  • ~/.mix/dialyxir_erlang-19.3.plt
  • ~/.mix/dialyxir_erlang-19.3_elixir-1.4.0.plt
  • _build/dev/dialyxir_erlang-19.3_elixir-1.4.0_deps-dev.plt

I removed all three, and ran it again to make sure it built them cleanly. As far as I can see from dialyzer --plt_info, the first contains core Erlang stuff, and the second core Elixir stuff plus everything that was in the first. The third is where I’d expect to find the dependencies, but it actually seems to be an exact copy of the second.

Am I right to expect deps to be in this file? Any thoughts as to why they might not be?

That would be my expectation as well. Have a look at

https://hexdocs.pm/dialyxir/readme.html#with-explaining-stuff

the “Dependencies” section

The default behaviour is supposed to be something equivalent to

def project do
 [ app: :my_app,
   version: "0.0.1",
   deps: deps,
   dialyzer: [plt_add_deps: :app_tree]
 ]
end

The attention being on plt_add_deps: :app_tree.

As an experiment you could try adding , plt_add_deps: :gettext at the end of the dialyzer list - it shouldn’t make a difference as :gettext is listed when mix runs but one never knows.

I’d also try plt_add_deps: :transitive and plt_add_deps: :project separately just to see what happens.

I did have it set to :transitive, but tried switching to :project. That got rid of most of the errors, only leaving unknown functions from Phoenix.Plug. I added :plug as an explicit application in the mixfile for the web app, and those errors disappeared too.

I’m still not sure why it suddenly broke, or whether this is the “correct” fix, but at least it’s working again now and I can concentrate on fixing the error in my code that it warned me about before it started playing up.

Many thanks for your help!