OmegaNalphA

OmegaNalphA

Dialyzer error - trying to handle :error responses with multiple values in the error tuple

I’m having an issue getting my Dialyzer to agree with my output, and can’t seem to figure it out. Essentially, the response is {:error, %Mint.HTTP2{}, %Mint.HTTPError{}} instead of just {:error, _} and I can’t get the spec to reflect that.

This is the issue I’m facing, I keep getting an error from my Mint transport service (which is a whole separate issue) but I keep getting alerts that my handle_response isn’t able to match the type. After looking into it more the error tuple has two arguments in the shape of: {:error, %Mint.HTTP2{}, %Mint.HTTPError{}}.

Here is my handle_response:

  @spec handle_response(
          {:ok, [map()] | function()}
          | {:error, String.t()}
          | {:error, %Mint.HTTP2{}, %Mint.HTTPError{}},
          Keyword.t()
        ) ::
          {:ok, [map()] | function()} | {:error, term()}
  defp handle_response(resp, opts)

  defp handle_response({:ok, stream} = resp, stream: true) when is_function(stream), do: resp

  defp handle_response({:ok, resp}, opts) when is_binary(resp),
    do: handle_response({:ok, Jason.decode!(resp)}, opts)

  defp handle_response({:ok, resp}, _), do: {:ok, Map.get(resp, "choices", [])}

  defp handle_response({:error, _} = err, _), do: err

  defp handle_response({:error, http, http_error}, _)
       when is_map(http) and is_map(http_error),
       do: {:error, http_error}

But I keep getting an error from my dialyzer here:

lib/broadcast.ex:129:pattern_match
The pattern can never match the type.

Pattern:
{:error, _http, _http_error}, _

Type:
{:error, _} | {:ok, _}, [{:stream, _}, ...]

I’m not sure why, I’m pretty sure the spec should be correct. Can anyone see what would be incorrect about this or does this seem reasonable?

Marked As Solved

al2o3cr

al2o3cr

(assuming that do_generate and the handle_response from your initial post are in the same module)

Dialyzer is telling you the {:error, _, _} branch in handle_response can’t be reached because create_completion’s return type matches Client.handle_response ({:ok, body()} | {:error, term()})

As shown, Client.handle_response will crash if Client.post returns {:error, _, _}, since it doesn’t have a matching clause. You’ll likely need to update:

  • the definition of result in Client, if it doesn’t include the 3-tuple case already
  • the return type for Client.handle_response, if you want to handle the 3-tuple case in the caller instead of in Client

Also Liked

LostKobrakai

LostKobrakai

One thing to understand with dialyzer is that it starts out not caring about your spec at all.

Dialyzer does type inference. And for the given functions it inferred that the input will never be a tuple-3. Your function matches on such a tuple though, which is surfaced as an error.

The spec of the function is compared against inferred values and mismatches (as in the spec doesn’t have overlap with the inferred value) are reported. Iirc the overlap between the inferred type and the spec for the return type is then used as the input to later inferrence.

So an incorrect typespec can mess up validation on deeped down in the callstack function calls, but typespec cannot “widen” what would be considered a possible input to a function call compared to the inferred value.

al2o3cr

al2o3cr

Can you show the code that calls handle_response? The error message suggests that Dialyzer has inferred that the {:error, map(), map()} case “can’t happen” despite it being observed in production.

Where Next?

Trending in Questions Top

lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
senggen
Erlang/OTP 25 [erts-13.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] 15:22:35.803 [error] gen_event {lager_file_backend...
New
hariharasudhan94
Lets say I have map like this fetching from my database %{"_id" => #BSON.ObjectId<58eb1a7a9ad169198c3dXXXX>, "email" => ...
New
tj0
I’ve been following the steps here for the upgrade from 1.6 to 1.7 and it has gone relatively smoothly all the way till the phoenix_view ...
New
cgraham
Hi! What is currently the best library/method for parsing text and tabular data out of PDF files in Elixir or Erlang?
New
stefanchrobot
Hi, I need a way to handle data migrations in my application. I found an article by @wojtekmach about manual migrations: Automatic and ma...
New
stjefim
Hello! Suppose you are building workflow (order / task / payment) processing system with the following requirements: Each workflow con...
New

Other Trending Topics Top

GenericJam
Edit: 2026 May 15 - This post is archived. Mob is alive!! Main docs: mob v0.7.11 — Documentation A bit of explanation for the slightly c...
New
JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
kip
Localize is the next generation localisation library for Elixir. Think of it as ex_cldr version 3.0. The first version will be released ...
New
webofbits
Squid Mesh is an open source workflow automation runtime for Elixir applications. It is aimed at Phoenix and OTP apps that want to defin...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
kip
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New

We're in Beta

About us Mission Statement