[Bug]: Registry server crashes when the update checker writes last_update after the registry was closed

Abierto Apto para principiantes
#1,310 0 comentarios 0 reacciones 0 asignados Ver en GitHub

Los mantenedores suelen responder en 1 día

Nadie ha tomado este issue todavía.

Evaluación

Dificultad
2/5
Tiempo estimado
1-3 horas
Aptitud para principiantes
84/100
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
elixir, erlang
Área
backend, cli

Línea de trabajo

Lee los manejadores :close y :last_update en lib/hex/registry/server.ex y, después, sigue la llamada desde lib/hex/update_checker.ex y las llamadas a :close en lib/mix/tasks/hex.package.ex. Confirma cómo se comporta el manejador cuando el estado del registro tiene ets: nil. La tarea está terminada cuando se ignora una escritura tardía de last_update sin que el registro se bloquee; añade o actualiza una prueba para ese caso.

Escrito por el modelo de indexación a partir del texto del issue.

Descripción

Product or component

hexpm/hex: Package manager client CLI and Mix task integration for Erlang/Elixir

Summary

The update checker's last_update write can reach a registry that its task already closed. handle_call({:last_update, time}, ...) then runs :ets.insert(nil, ...) and the registry server crashes. This is the crash in #936 and #996, both closed as not reproducible; below is the cause.

What happened?

Opening the registry casts Hex.UpdateChecker.start_check/0 (lib/hex/registry/server.ex, the :open handlers), which starts an async request for the Hex installs list. When it returns, Hex.UpdateChecker.handle_info/2 calls Hex.Registry.Server.last_update/1 (lib/hex/update_checker.ex, line 76).

Some tasks close the registry themselves before that request returns, for example mix hex.package fetch (lib/mix/tasks/hex.package.ex, the Hex.Registry.Server.close() calls). After :close the state has ets: nil, and lib/hex/registry/server.ex line 439 runs :ets.insert(state.ets, {:last_update, time}), which crashes the server. A caller waiting on the registry, such as a later close/0, receives that crash as an exit.

Because the write never lands, last_update is never saved, so a fresh HEX_HOME (for example in CI) runs the update check, and can hit this crash, on every command. In our CI it failed 2 of 2 runs on 2026-11-08.

What did you expect?

A last_update write after the registry was closed should be ignored, not crash the registry.

Steps to reproduce
  1. Use an empty HEX_HOME.
  2. Run mix hex.package fetch <package> <version> repeatedly.
  3. It crashes whenever the installs request returns after the task's own registry close. The timing varies; #936 shows the same crash from mix archive.install hex phx_new and #996 from Mix.install/1.
Environment / context
  • Hex 2.6.0; the same code is on main (2.8.0-dev, 986d4e6)
  • Elixir 1.20.4, Erlang/OTP 29.1.2
  • Linux, x86_64
Logs / screenshots
GenServer Hex.Registry.Server terminating
** (ArgumentError) errors were found at the given arguments:
  * 1st argument: the table identifier does not refer to an existing ETS table
    (stdlib) :ets.insert(nil, {:last_update, {{2026, 11, 8}, {15, 7, 42}}})
    (hex 2.6.0) lib/hex/registry/server.ex:439: Hex.Registry.Server.handle_call/3
Last message (from Hex.UpdateChecker): {:last_update, {{2026, 11, 8}, {15, 7, 42}}}
State: %{ets: nil, ...}
Additional context

Possible fix: ignore the write when the registry is closed, for example

def handle_call({:last_update, _time}, _from, %{ets: nil} = state) do
  {:reply, :ok, state}
end

or have the update checker skip last_update/1 when the registry is not open.

Lenguaje dominante
Elixir
Estrellas
1.1k
Forks
214
Merge medio
16 h 50 min
PR fusionados (30 d)
38

Preparar el entorno

Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de hexpm/hex

Todos los issues de hexpm/hex

Issues similares

Más issues de Elixir

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.