dialyxir icon indicating copy to clipboard operation
dialyxir copied to clipboard

Dialyxir is not invalidating the PLT if erlang version changes

Open michelboaventura opened this issue 2 years ago • 4 comments

Environment

Erlang/OTP 24 [erts-12.1.4] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]
Elixir 1.12.0 (compiled with Erlang/OTP 24)
cat mix.lock | grep dialyxir
"dialyxir": {:hex, :dialyxir, "1.1.0", "c5aab0d6e71e5522e77beff7ba9e08f8e02bad90dfbeffae60eaf0cb47e29488", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "07ea8e49c45f15264ebe6d5b93799d4dd56a44036cf42d0ad9c960bc266c0b9a"},

Current behavior

From time to time I'm seeing this behavior on my CI runs:

$ mix dialyzer
Finding suitable PLTs
Checking PLT...
[(some modules)]
PLT is up to date!
No :ignore_warnings opt specified in mix.exs and default does not exist.

Starting Dialyzer
[
  check_plt: false,
  init_plt: 'PROJECT/_build/plts/dialyzer.plt',
  files: [(some files)]
  warnings: [:error_handling, :race_conditions, :unknown, :unknown]
]
:dialyzer.run error: Old PLT file PROJECT/_build/plts/dialyzer.plt

So Dialyxir thinks the PLT is fine but dialyzer itself disagrees. After digging a bit more it seems to be caused by my CI updating Erlang from a new version but within the same OTP, ie from 24.0 to 24.1.4.

I was able to reproduce the error by generating the PLT with erlang 24.0, updating it to 24.1 and executing mix dialyzer again.

So it seems dialyxir isn't taking erlang into consideration while validating PLT, although I couldn't find the issue scanning its source code.

Expected behavior

I think dialyxir should consider the PLT invalid if erlang version changes.

michelboaventura avatar Nov 02 '21 21:11 michelboaventura

It looks like you are using plt_file option which is deprecated for this reason and writes a warning when you use it. If you don't use that, then the PLT file name includes the version of Erlang & Elixir.

jeremyjh avatar Nov 05 '21 13:11 jeremyjh

I would like to add though, that you will face other problems with what you are doing. Your CI cache needs to be purged when versions of Erlang and Elixir change. Also, I'd encourage you to take control of your build container so that your builds are repeatable and version upgrades happen when you plan for them to happen.

jeremyjh avatar Nov 05 '21 13:11 jeremyjh

Hey @jeremyjh thanks for the reply. I'm using plt_file following the example on README.md. But taking another look at it I can now see erlang/elixir versions are fixed, so this issue won't happen, right?

But even if I use plt_file and update Elixir the plt is regenerated automatically, so it seems to happen only on Erlang updates.

michelboaventura avatar Nov 05 '21 15:11 michelboaventura

I had the same "Old PLT file" problem in my CI pipeline after updating Erlang to a new version. In my case, the cache responsible for storing Dialyzer plts had a static key (e.g., plts), so including Erlang and Elixir versions in the key (plts-$ELIXIR_VERSION-$ERLANG_VERSION) solved the issue.

smaximov avatar Dec 27 '22 09:12 smaximov