Skip to content

Dialyzer warnings with Elixir 1.19.3 in RingBuffer module #663

@maurymmarques

Description

@maurymmarques

Summary

Dialyzer is reporting type warnings in Honeybadger.Breadcrumbs.RingBuffer when using Elixir 1.19.3. The warnings occur during struct updates where the Dialyzer expects explicit struct pattern matching.

Environment

  • Elixir version: 1.19.3
  • Erlang/OTP version: 28.1.1
  • Honeybadger version: 0.24.1
  • Dialyxir version: 1.4.7

Warnings

warning: a struct for Honeybadger.Breadcrumbs.RingBuffer is expected on struct update:

    %Honeybadger.Breadcrumbs.RingBuffer{ring | buffer: rest ++ [item]}

but got type:

    dynamic(%{..., buffer: non_empty_list(term(), term()), ct: term(), size: term()})

where "ring" was given the type:

    # type: dynamic(%{..., buffer: non_empty_list(term(), term()), ct: term(), size: term()})
    # from: lib/honeybadger/breadcrumbs/ring_buffer.ex:20:16
    ring = %{ct: ct, size: ct, buffer: [_head | rest]}

when defining the variable "ring", you must also pattern match on "%Honeybadger.Breadcrumbs.RingBuffer{}".

hint: given pattern matching is enough to catch typing errors, you may optionally convert the struct update into a map update. For example, instead of:

    user = some_function()
    %User{user | name: "John Doe"}

it is enough to write:

    %User{} = user = some_function()
    %{user | name: "John Doe"}

typing violation found at:

  │
21 │     %__MODULE__{ring | buffer: rest ++ [item]}
  │     ~
  │
  └─ lib/honeybadger/breadcrumbs/ring_buffer.ex:21:5: Honeybadger.Breadcrumbs.RingBuffer.add/2

Similar warning appears at line 25 for:

%__MODULE__{ring | buffer: buffer ++ [item], ct: ct + 1}

Expected Behavior

No Dialyzer warnings should appear when compiling the project.

Actual Behavior

Dialyzer reports type warnings in the RingBuffer.add/2 function at lines 21 and 25.

Possible Cause

Elixir 1.19 introduced improvements to the type system and Dialyzer integration. The warnings suggest that Dialyzer now requires explicit struct pattern matching when performing struct updates. The current code pattern matches on a map (ring = %{ct: ct, size: ct, buffer: [_head | rest]}) but then tries to update it as a struct.

Suggested Fix

According to the Dialyzer hint, the code should either:

  1. Pattern match on the struct explicitly:

    %__MODULE__{} = ring = %{ct: ct, size: ct, buffer: [_head | rest]}
    %__MODULE__{ring | buffer: rest ++ [item]}
  2. Or use map update syntax:

    ring = %{ct: ct, size: ct, buffer: [_head | rest]}
    %{ring | buffer: rest ++ [item]}

Impact

  • Severity: Low (warnings only, code compiles and runs correctly)
  • Affected users: Anyone using Elixir 1.19+ with Honeybadger 0.24.1
  • Workaround: Warnings can be ignored or suppressed via Dialyzer configuration

Additional Notes

These are type warnings from Dialyzer, not compilation errors. The code functions correctly, but the warnings may be confusing for developers and could indicate potential type safety issues.

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions