Dialyzer giving warnings that make no sense


I have recently started trying out dialyxir. After playing around with a few pet projects I decided to up the game and try it into something more real.


However, dialyxir is giving me warnings that make no sense whatsoever. Thanks to the success algorithm dialyzer uses, I would expect it to not find every possible error which is fine, but giving me so many false positives ( which should be impossible ) is definitely something I was not expecting - it completely ruins the experience with noisy warnings that are useless.

Have a look on the following behaviour:

defmodule MyApp.Web.MetricsInstrumenter do
  @moduledoc """
  Adds HTTP related metrics for every request.
  See used Prometheus.PlugPipelineInstrumenter module for details.
  use Prometheus.PlugPipelineInstrumenter

This created the following dialyxir warning:

Guard test:
tuple_size(_ :: Exception.t())

can never succeed.

This is mind blowing. This makes no sense whatsoever. There is literally only 1 line of code and that line doesn’t even have a when clause.

Why am I getting this error?


I keep thinking this is a configuration problem. Somehow, I am not configuring the app correctly in the mix.exs file while using Prometheus.

defmodule MyApp.MixProject do
  @moduledoc false
  use Mix.Project

  def project do
      app: :myaap,
      version: "1.1.0",
      elixir: "~> 1.7",
      elixirc_paths: elixirc_paths(Mix.env()),
      start_permanent: Mix.env() == :prod,
      deps: deps()

  def application do
      extra_applications: [:logger],
      mod: {MyApp.Application, []}

  defp deps do
      { :plug,              "~> 1.0"  },
      { :prometheus_plugs,  "~> 1.1.5"  },
      { :prometheus_ex,     "~> 3.0"  },
      { :dialyxir,          "~> 1.0.0-rc.4",  only: [:dev],         runtime: false  }

  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(:dev), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

But nothing I do works.
Why am I getting these non nonsensical errors?

Thats hard to tell from this perspective, but probably something in prometheus is faulty?

In general it makes totally sense that tuple_size/1 called with an exception as argument would not suceed. Problem is though, I can not find any reference to tuple_size/1 in either prometheus_plugs, nor prometheus_ex.

So this problem might be burried even deeper.


Can’t even find tuple_size it in the underlying erlang library. I’m trying to dig into this locally. Dialyzer is building its PLT right now…


@NobbZ Just to make it clear, I truly appreciate all the help you are giving. Without you this forum wouldn’t be what it is today.

Thank you.

On a separate note, if this is an issue with Prometheus, what are the options?

  1. make a PR to fix it?
  2. ask dialyzer to ignore prometheus_ex ? ( not sure if even possible )

If it is, you can configure dialyzer to ignore it. In dialyxirs README there should be a section about ignoring.

I’d report it upstream anyway.

But before reporting anything, we have to wait a bit. Dialyzer hasn’t found any issues in prometheus_ex itself, so now I have tried to create an example project from what you gave us so far and I am running dialyxir on it. This means building PLTs again.

Sorry, but with the information you have provided so far I am unable to reproduce the issue.

Can you create a minimal project that shows the problem and publish it on github or somewhere else?



I got the same class of errors as described. They’re everywhere.

On my current machine (elixir 1.6/OTP20) there are no issues. I have currently not the resources available to update to 1.7/21 here, but I will try again when I’m back at home, where my setup is more up to date.

Spoiler warning… I sshd into my system at home which runs 1.7/21. It triggers the same errors as you report. Ill have to play a bit with versions to learn more…


I just asked for a friend to test in his machine using 1.7.3-otp-21 and he gets the same issues. On a clean machine with a fresh 1.7.3-otp-21 install.

I will wait for you to get home. If you verify there is in fact something odd, then I believe we should create an issue and report it. Where to report it? Not sure. Not sure if this is an issue with dialyxir or prometheus, though I am leaning towards the 1st one because it seems to work fine with older versions.

This seems to happen in the expansion of Prometheus.Error.with_prometheus_error/1, as the same messages appear when I run dialyzer in the prometheus_ex code base at places where that macro is used:

lib/prometheus/format/protobuf.ex:13: Guard test tuple_size(__@5::#{'__exception__':='true', '__struct__' :=_, _=>_}) can never succeed
lib/prometheus/format/protobuf.ex:21: Guard test tuple_size(__@5::#{'__exception__':='true', '__struct__' :=_, _=>_}) can never succeed
lib/prometheus/format/text.ex:26: Guard test tuple_size(__@5::#{'__exception__':='true', '__struct__':=_, _=>_}) can never succeed
lib/prometheus/format/text.ex:34: Guard test tuple_size(__@5::#{'__exception__':='true', '__struct__':=_, _=>_}) can never succeed  

The output is from dialyxir ~> 0.5.0, as that is the specified dependency of prometheus_ex.

As in that macro some testing about the availability of __STACKTRACE__ is done, I have to assume this is due changes in OTP 21 (or has it been in 20?) and exception handling. This is definitifely something that needs to be reported at prometheus.ex.

1 Like

Its even worse and I will prepare a bug report to elixir, as I can reproduce the issue with the following minimal module:

defmodule Foobar do
  def hello do
    try do
      e in ErlangError ->
1 Like

Its already reported and closed:


I’m not sure though, if the fix is in the 1.7 branch or only for 1.8.


I also had encountered this problem when working with Prometheus library and the problem indeed was in Elixir itself, however I believe it was released as a fix in one of 1.7.x versions.

I however fixed the problem twofold:

  1. Firstly I fixed prometheus_ex library that was needlessly using a lot of macros for no reason.
  2. Ditched prometheus_ex at all and replaced it with plain prometheus library (Erlang one) as this one has IMHO much cleaner interface.
1 Like

@NobbZ Thanks for all the help really!
Didn’t think this path would take us to an elixir bug, I am fairly surprised!

It will be interesting to see when they fix this. So for now I guess I can’t use elixir 1.7.3-otp-21. Which version would work?

Is there a place where I can check all elixir 1.7.X-otp-Y builds available? I assume I now have to try with several and see which one works with the project.

@hauleth I am always amazed when I see someone make PR with code to such a big project and get it accepted. I usually only do documentation because my time is not enough to understand a library deeply enough in order to make those kinds of PRs.

Still, I am surprised to see you completely ditched prometeus_ex. Unfortunately this is not something I can do in the project I have. First, because it is a company project and I can’t do whatever I want. Second, because I actually have hopes that the bug will be fixed in the future and I will be able to use diallyzer.

Not Ideal, I know, but for now finding an elixir/otp compatible build is my best option, the way I see it.