Elixir: protocol Enumerable not implemented for nil of type Atom
Something handed `Enum` a nil where a list was expected, and nil has no Enumerable implementation. The real fault is upstream: an Ecto association that was never preloaded, a `Map.get` that missed, or a function whose error branch returns nil instead of an empty list.
Quick fix
Read the commands before running them. Anything that restarts a service, deletes data or changes permissions should be tried on a non-production system first.
# Ecto is the usual source: an unloaded association is a struct, not a list
iex> post.comments
#Ecto.Association.NotLoaded<association :comments is not loaded>
Repo.get!(Post, id) |> Repo.preload(:comments)
from(p in Post, preload: [:comments]) |> Repo.all()
# Make the empty case explicit rather than letting nil travel
Enum.map(list || [], &process/1)
# Or match it, so the failure lands where the value was produced
case fetch_items() do
{:ok, items} -> Enum.map(items, &process/1)
{:error, reason} -> Logger.error("no items: #{inspect(reason)}")
end
# The same message for a struct means the struct needs a real implementation,
# usually by deriving it or by calling Map.to_list/1 first
How to diagnose Elixir errors
Elixir errors are shaped by the actor model: a GenServer.call timeout does not mean the server crashed, it means the server was busy for longer than the caller was willing to wait. The right question is usually "what is that process doing?" rather than "why did the call fail?". Because supervisors restart failed processes automatically, transient errors can also hide in the logs while the system appears healthy.
If the quick fix above does not resolve it, work through these steps. They apply to this whole class of error, not just to this one message, which is usually what saves the time.
- Attach to a running node with
iex --remshand inspect the process:Process.info(pid, :message_queue_len). A growing mailbox means the process is the bottleneck. - Use
:observer.start()to see the supervision tree, process memory and message queues visually. - Move long-running work out of
handle_call. Usehandle_cast, a Task, or a dedicated pool so the GenServer stays responsive. - Check restart intensity. A supervisor that exceeds
max_restartstakes down its own supervisor, producing a cascade that looks like an unrelated failure at the top. - For compile errors in dependencies, run
mix deps.compile --forceand check that any required native toolchain (make, gcc, erlang headers) is installed.
Tools worth reaching for
:observer.start()iex --remshProcess.info/2mix deps.tree:recon
Authoritative references
Primary documentation for this error, worth reading before applying any fix in production.
Related Elixir errors
- Ecto: connection not available and request was dropped from queueEvery connection in the pool was busy for longer than queue_target allowed, so DBConnection…
- Elixir: (FunctionClauseError) no function clause matchingEvery clause of the function was tried and none matched the arguments, either on the pattern…
- Elixir: (KeyError) key :name not found in: %{"name" => "ada"}Dot access and `Map.fetch!/2` raise rather than returning nil when a key is missing, and the…
- Elixir: function Foo.bar/1 is undefined (module Foo is not available)The module was never loaded, which in practice means a misspelled alias, a file outside the…
- Elixir: GenServer call timeout (exited in :gen_server.call)A GenServer.call did not get a reply within 5000ms (default) because the server is…
- Elixir: Mix could not compile dependencyA dependency failed to compile due to missing native build tools, a version conflict, or…
- Phoenix: (Phoenix.Router.NoRouteError) no route found for GET /api/usersNo clause in the router matched, so Phoenix raises rather than quietly returning 404 in…
- Phoenix: WebSocket connection rejected by check_originPhoenix rejects socket connections whose Origin header is not in the allowed list. Behind a…
Browse other categories
- HTTP 494xx client errors, 5xx server errors, redirects, headers and protocol problems.
- JavaScript 42npm resolution, async pitfalls, hydration, memory limits and runtime type…
- Database 41Connections, deadlocks, constraints, replication and memory limits.
- AI 35Rate limits, context windows, GPU memory and model-serving failures.
- Network 35Refused connections, timeouts, resets, MTU problems and port exhaustion.
- Python 35Imports, virtual environments, encoding, concurrency and dependency conflicts.
- Kubernetes 34CrashLoopBackOff, ImagePullBackOff, OOMKilled, RBAC, scheduling and storage.
- Docker 27Daemon connectivity, disk space, image pulls, ports and architecture mismatches.
- System 26Disk space, systemd units, file descriptors, OOM killer and scheduled jobs.
- Cloud 25IAM permissions, quotas, service limits and credential failures.
- Security 25JWT validation, CSRF, OAuth grants, SELinux, SSH host keys and CSP.
- TLS 24Untrusted authorities, expiry, hostname mismatch, chains and cipher negotiation.
Something missing or wrong?
This entry is maintained by hand. If the fix is out of date, incomplete, or you have a better one, email a correction and it will be reviewed.