Skip to content

Dynamic repo names collisions across different Ecto.Repo modules #4647

@pnezis

Description

@pnezis

Elixir version

{"Erlang/OTP 27 [erts-15.0] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [jit]\n\nElixir 1.17.1 (compiled with Erlang/OTP 27)\n",

Database and Version

Irrelevant

Ecto Versions

3.13

Database Adapter and Versions (postgrex, myxql, etc)

postgrex

Current behavior

Issue 1: Global Name Collision

Starting two different repo modules with the same :name causes the second one to fail.

defmodule Repo do
  use Ecto.Repo,
    otp_app: :my_app,
    adapter: Ecto.Adapters.Postgres
end

defmodule AnotherRepo do
  use Ecto.Repo,
    otp_app: :my_app,
    adapter: Ecto.Adapters.Postgres
end

# This works
{:ok, _pid1} = Repo.start_link(name: :foo, hostname: ...)

# This fails with name collision
AnotherRepo.start_link(name: :foo, hostname: ...)
# {:error, {:already_started, _pid1}} 

Issue 2: Unsafe Cross-Repo Dynamic Access

put_dynamic_repo/1 can reference repos from completely different modules, breaking encapsulation and potentially causing data integrity issues.

When repos implement different callbacks cross-module dynamic repo access can cause queries to execute with the wrong repo's
callbacks, leading to silent failures or unexpected behavior.

# Start repos with different names
{:ok, _pid1} = Repo.start_link(name: :primary_db, hostname: ...)
{:ok, _pid2} = AnotherRepo.start_link(name: :analytics_db, hostname: ...)

# This should fail but currently works
Repo.put_dynamic_repo(:analytics_db)  # Now Repo queries go to AnotherRepo's database!

# Any subsequent Repo operations now target :analytics_db
Repo.all(SomeSchema) 

Expected behavior

  • Different Ecto repo modules should be able to use the same process names without conflicts, as they are separate modules with potentially different purposes. If this is intentional this should be documented.

  • Repo.put_dynamic_repo/1 should only accept repos that belong to the same module, or at minimum validate that the target repo is compatible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions