# WARNING: both X and Y export "F"; uses of it in module Z must be qualified

**URL:** <https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574>\
**Category:** New to Julia\
**Created:** [April 30, 2025, 2:12pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574 "2025-04-30T14:12:52Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [April 30, 2025, 2:12pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/1 "2025-04-30T14:12:52Z")

</div>

Some versions of Julia reported warnings like these ones:

> WARNING: both IOExtras and Base export “readuntil”; uses of it in module WebSockets must be qualified  
> WARNING: both IOExtras and Base export “readuntil”; uses of it in module Strings must be qualified

These warnings seem to have gone now. What were the considerations to remove this? Was there a (community) discussion? I can’t access the git history over the company network for a closer investigation.

---

<div class="post-metadata">

**Author:** ![cjdoris](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/cjdoris/32/213133_2.png) [@cjdoris](https://discourse.julialang.org/u/cjdoris)\
**Post date:** [April 30, 2025, 2:27pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/2 "2025-04-30T14:27:35Z")

</div>

Are you sure it was a change in Julia? Probably it’s just that those mentioned packages fixed their imports.

---

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [April 30, 2025, 2:29pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/3 "2025-04-30T14:29:37Z")

</div>

I downloaded the source code of Julia from [GitHub - JuliaLang/julia: The Julia Programming Language](https://github.com/JuliaLang/julia) as a zip file and grepped. I think the code to display the warning is gone.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 30, 2025, 2:32pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/4 "2025-04-30T14:32:44Z")

</div>

This does change in the v1.12-beta. It’s part of the larger overhaul to how bindings are resolved and replaced. Documentation is in the process of being written.

> <https://github.com/JuliaLang/julia/pull/58253>

You do still get a hint here:

```julia-repl
julia> module X
       f = 1
       export f
       end
Main.X

julia> module Y
       f = 2
       export f
       end
Main.Y

julia> using .X, .Y

julia> f
ERROR: UndefVarError: `f` not defined in `Main`
Hint: It looks like two or more modules export different bindings with this name, resulting in ambiguity. Try explicitly importing it from a particular module, or qualifying the name with the module it should come from.

```

---

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [April 30, 2025, 2:53pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/5 "2025-04-30T14:53:56Z")

</div>

I am aware of the way to generate the runtime error. I was just wondering why the specific warning was removed. Apparently this is under reconstruction, which is perfectly fine. Can I safely assume that a similar warning will be generated by Julia in 1.12 while precompiling?

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 30, 2025, 3:03pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/6 "2025-04-30T15:03:25Z")

</div>

> [@Matthijs\_1971](#):
>
> Can I safely assume that a similar warning will be generated by Julia in 1.12 while precompiling?

I don’t think so, not unless you actually touch the ambiguous binding. But I’m not certain on this point yet myself.

---

<div class="post-metadata">

**Author:** ![ufechner7](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ufechner7/32/51363_2.png) [@ufechner7](https://discourse.julialang.org/u/ufechner7)\
**Post date:** [April 30, 2025, 3:16pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/7 "2025-04-30T15:16:05Z")

</div>

I can confirm that I get these warnings when precompiling using Julia 1.10, and not when using Julia 1.11. Now I wonder: Should I try to fix these warnings or not?

---

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [April 30, 2025, 3:48pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/8 "2025-04-30T15:48:50Z")

</div>

Uhm… as I understand it, the warning indicates up front that the client package will error if Julia actually hits the lines if warned about earlier. Qualification of the intended serving package solves the ambiguity and it is as simple as adding the package name to the call. So `f()` becomes either `X.f()` or `Y.f()` if there are two packages involved. Probably you are the one using your code the most, so you are most affected if your nightly calculations fail over such triviality, so fixing it in your source code is a good idea IMHO. I am truly risk-averse, so I qualify anything that can be qualified. As a result, if (future) changes to client packages cause collisions like this, my code still runs because it is already qualified. So I am a fan of `import` rather than `using`, because `import` forces qualification.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 30, 2025, 4:02pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/9 "2025-04-30T16:02:13Z")

</div>

Yeah, if there are two packages that are frequently used together, it might be something you want to pro-actively flag. Otherwise, it’s just fine unless you actually trip over it.

To me, this seems like a very similar case as method ambiguity detection. A long long time ago, we warned at _any_ prospect of method ambiguities at definition time. That was very noisy and not needed in practice, so instead it moved into a test — you ensure `X` and `Y` don’t have ambiguities when used together with `Test.detect_ambiguities(X, Y)`.

I think this warning is similarly better served as an explicit test. I’m not sure how to best construct such a test, though.

---

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [April 30, 2025, 4:22pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/10 "2025-04-30T16:22:57Z")

</div>

Well… such a test needs to be executed repeatedly and maintenance needs to be done to the depending package - just to be able to omit the package name. Also, developers benefit from the qualification, I think, especially if many packages are used. The package name improves code readability - but that is subjective.

The danger I see is as follows: Package P depends on packages A and B. Package P has `using A` and `using B`. Package A exports function `f` and P uses it without qualification because `A` exports it. Package P is finished and in production at some point. Now a developer of B implements a function called `f` in B with the same signature. As a result, P is broken due to the changes of B. There is no CI/CD pipeline that warns for it, because there is no delta in P. Now, one could argue that the Project.toml of P should restrict the upgrades of A and B… but that brings a dependency hell a step closer. Therefore, I like qualification. I don’t need to check that P needs maintenance - I have done it already pro-actively like you indicate. The “tripping over it” is a risk for my company and its customers, I think. Now my package needs maintenance when `A.f` is changed without backwards compatibility, but I think that risk is smaller and unavoidable.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [April 30, 2025, 4:36pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/11 "2025-04-30T16:36:00Z")

</div>

I think the solution there is for Package `P` to run [ExplicitImports.jl](https://github.com/ericphanson/ExplicitImports.jl). Then it doesn’t matter if `A` or `B` introduce conflicting bindings; all bindings are explicitly resolved in `P`.

---

<div class="post-metadata">

**Author:** ![Matthijs\_1971](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@Matthijs\_1971](https://discourse.julialang.org/u/Matthijs_1971)\
**Post date:** [May 1, 2025, 11:13am UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/12 "2025-05-01T11:13:13Z")

</div>

~~ExplictImports requires Julia 1.12~~ , so I installed julia-1.12.0-beta2 for Linux. After some fiddling around, I got similar warnings on my terminal:

```julia
Precompiling packages finished.
  432 dependencies successfully precompiled in 449 seconds. 55 already precompiled.
  4 dependencies had output during precompilation:
 StableRNGs
  WARNING: Constructor for type "Sampler" was extended in `StableRNGs` without explicit qualification or import.
    NOTE: Assumed "Sampler" refers to `Random.Sampler`. This behavior is deprecated and may differ in future versions.`
    NOTE: This behavior may have differed in Julia versions prior to 1.12.
    Hint: If you intended to create a new generic function of the same name, use `function Sampler end`.
    Hint: To silence the warning, qualify `Sampler` as `Random.Sampler` in the method signature or explicitly `import Random: Sampler`.
  
 WebSockets
  WARNING: Imported binding Logging.termlength was undeclared at import time during import to WebSockets.
  WARNING: Imported binding Logging.showvalue was undeclared at import time during import to WebSockets.
  
 UTCDateTimes
  WARNING: Constructor for type "DateTime" was extended in `UTCDateTimes` without explicit qualification or import.
    NOTE: Assumed "DateTime" refers to `<null>.DateTime`. This behavior is deprecated and may differ in future versions.`
    NOTE: This behavior may have differed in Julia versions prior to 1.12.
    Hint: If you intended to create a new generic function of the same name, use `function DateTime end`.
    Hint: To silence the warning, qualify `DateTime` as `<null>.DateTime` in the method signature or explicitly `import <null>: DateTime`.
  
 PlotlyBase DistributionsExt
  WARNING: Constructor for type "Plot" was extended in `DistributionsExt` without explicit qualification or import.
    NOTE: Assumed "Plot" refers to `PlotlyBase.Plot`. This behavior is deprecated and may differ in future versions.`
    NOTE: This behavior may have differed in Julia versions prior to 1.12.
    Hint: If you intended to create a new generic function of the same name, use `function Plot end`.
    Hint: To silence the warning, qualify `Plot` as `PlotlyBase.Plot` in the method signature or explicitly `import PlotlyBase: Plot`.
  
  12 dependencies errored.
  For a report of the errors see `julia> err`. To retry use `pkg> precompile`
        Info We haven't cleaned this depot up for a bit, running Pkg.gc()...
      Active manifest files: 6 found
      Active artifact files: 119 found
      Active scratchspaces: 7 found
     Deleted 33 package installations (11.357 MiB)
     Deleted 2 artifact installations (34.462 MiB)

julia> 

```

So it looks like these will replace the previous ones. I tried to reproduce this output, but that failed. Precompiling again suppresses this output. Is there a way to generate it again without using ExplictImports?

Indeed, it looks like ExplicitImports is a cool package. It clearly invites to change code in a good direction. Thanks for pointing it out.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [May 1, 2025, 1:47pm UTC](https://discourse.julialang.org/t/warning-both-x-and-y-export-f-uses-of-it-in-module-z-must-be-qualified/128574/13 "2025-05-01T13:47:20Z")

</div>

Those warnings all look unrelated to ExplicitImports. You can reproduce all of these directly at the REPL:

```Julia
julia> module T
       using Random: Sampler
       Sampler() = ()
       end
WARNING: Constructor for type "Sampler" was extended in `T` without explicit qualification or import.
  NOTE: Assumed "Sampler" refers to `Random.Sampler`. This behavior is deprecated and may differ in future versions.
  NOTE: This behavior may have differed in Julia versions prior to 1.12.
  Hint: If you intended to create a new generic function of the same name, use `function Sampler end`.
  Hint: To silence the warning, qualify `Sampler` as `Random.Sampler` in the method signature or explicitly `import Random: Sampler`.

julia> module A
       export foo
       end
Main.A

julia> module B
       using ..A: foo
       end
WARNING: Imported binding A.foo was undeclared at import time during import to B.
Main.B

```

For packages, it’s probably true that they’ll only appear at precompile time. Removing the compiled files should get them to reappear.
