Skip to content
Latchkey

Elixir Dialyzer / Dialyxir PLT build failed in CI

Dialyzer needs a persistent lookup table (PLT) built from your deps and OTP. In CI it fails or times out when the PLT is missing and rebuilt every run, or reports type warnings that fail the gate.

What this error means

mix dialyzer errors with "Could not find ... PLT" / rebuilds the PLT on every run (slow), or exits non-zero on type warnings like "Function has no local return".

mix dialyzer
Could not find the project PLT at _build/dev/dialyxir_erlang-27.0_elixir-1.17.2.plt
Finding suitable PLTs ... none found, building from scratch

Common causes

PLT not cached, rebuilt every run

The PLT lives under _build. Without caching it (keyed on OTP/Elixir), each CI run rebuilds it from scratch, which is slow and can time out.

Real type warnings failing the gate

Dialyzer found a type discrepancy (an impossible pattern, a bad spec, no local return) and exits non-zero.

How to fix it

Cache the PLT keyed on the toolchain

  1. Cache the PLT directory keyed on OTP/Elixir and mix.lock.
  2. Build the PLT once, then reuse it across runs.
  3. Run mix dialyzer after the PLT is restored.
.github/workflows/ci.yml
- uses: actions/cache@v4
  with:
    path: priv/plts
    key: plt-${{ runner.os }}-otp${{ steps.beam.outputs.otp-version }}-elixir${{ steps.beam.outputs.elixir-version }}-${{ hashFiles('**/mix.lock') }}
- run: mix dialyzer --plt
- run: mix dialyzer

Fix the reported type discrepancy

Correct the @spec or the code path Dialyzer flags rather than ignoring the warning.

Terminal
mix dialyzer --format short

How to prevent it

  • Cache the PLT keyed on OTP, Elixir, and mix.lock.
  • Store PLTs in a fixed path via dialyzer: [plt_local_path: ...].
  • Treat Dialyzer warnings as real type issues to fix.

Frequently asked questions

What causes ""Could not find ... PLT" (Dialyzer)"?
The PLT lives under _build. Without caching it (keyed on OTP/Elixir), each CI run rebuilds it from scratch, which is slow and can time out.
How do I fix "Could not find ... PLT" (Dialyzer)?
Cache the PLT keyed on the toolchain

Related guides

References

Run this faster and cheaper on Latchkey managed runners - self-healing included. Start free → 30-day trial · No credit card