What is the URL of the page with the issue?

https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2#section-readme

What is your user agent?

Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36

Screenshot

Image

What did you do?

We have published a new version of our repo and have tagged our submodules using the same version number (v2.0.0). However, our docs are pointing to a version of these submodules from a year ago since our import paths have changed. For example, we see:

https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2/contrib/net/http

but we want:

https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/net/http/v2

In addition, the page pointed to by the CORRECT url is pointing to an old version. We expect it to be v2.0.0, but the latest version found is v2.1.0-dev.2. Could we get some assistance?

cc @darccio

What did you see happen?

Our submodule docs are generated with the wrong link.

The correct link does not go to the correct version.

What did you expect to see?

Our contribs point to the correct URL (...net/http/v2), and the correct URL displays the correct version (v2.0.0).

Comment From: thepudds

I haven’t poked around your repo, but would you mind clarifying how the tags were done?

From https://go.dev/ref/mod#module-path:

If the module is not defined in the repository’s root directory, the module subdirectory is the part of the module path that names the directory, not including the major version suffix. This also serves as a prefix for semantic version tags. For example, the module golang.org/x/tools/gopls is in the gopls subdirectory of the repository with root path golang.org/x/tools, so it has the module subdirectory gopls. See Mapping versions to commits and Module directories within a repository.

And:

If a module is defined in a subdirectory within the repository, that is, the module subdirectory portion of the module path is not empty, then each tag name must be prefixed with the module subdirectory, followed by a slash. For example, the module golang.org/x/tools/gopls is defined in the gopls subdirectory of the repository with root path golang.org/x/tools. The version v0.4.0 of that module must have the tag named gopls/v0.4.0 in that repository.

Comment From: hannahkm

Thanks for the reply @thepudds !

The problematic submodules we're seeing have a path like this: github.com/DataDog/dd-trace-go/contrib/net/http/v2 (so our go.mod file sits under the http folder), so we have tagged them like this: contrib/net/http/v2.0.0. From what I can tell, it seems like that's in alignment with the docs you linked?

Comment From: thepudds

~I’m not immediately seeing contrib/net/http/v2.0.0 tag on https://github.com/DataDog/dd-trace-go.~ [edit: back at a full-sized computer, I do see that tag, so maybe I was fooled by GitHub autocomplete behavior on mobile or otherwise made a mistake].

(But healthy chance I’m not following the relationships here, and also I’m on mobile 🙃)

To make it easier to follow, could you provide a GitHub link that shows the go.mod you expect at the tag you expect on the repo you expect?

Comment From: hannahkm

Yeah, understandable, we have a lot of tags! Sorry about that. But here is the tag (following my previous example of net/http), and the corresponding go.mod file that we are expecting to have the tag.

In general, our contrib folder follows the same pattern for all but two integrations (the exceptions being kafkatrace and os). We should see one go.mod file per submodule with the name github.com/DataDog/dd-trace-go/contrib/.../v2, and that should have a corresponding tag on GitHub with the name contrib/.../v2.0.0.

Comment From: thepudds

For this URL, which I think was called the correct URL in the opening comment:

https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/net/http/v2

I currently see version v2.0.0 of the github.com/DataDog/dd-trace-go/contrib/net/http/v2 module, which it says was published Jun 5, 2025.

Is that the desired version?

Comment From: hannahkm

Yes! Looks like that got published. Maybe pushing so many tags at once caused things to slow down. v2.0.0 is indeed the correct version.

At risk of jumping the gun again, it looks like the linked page is still showing the incorrect submodules though (i.e. a .../v2/contrib/... rather than /contrib/.../v2).

Comment From: thepudds

I'm just doing some light issue gardening as an external contributor (and I'm trying to avoid nerd-sniping myself into figuring out the history here 😅), but for the page you most recently linked to:

https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2@v2.0.0/contrib

Some quick observations:

  1. github.com/DataDog/dd-trace-go/v2/contrib is a Go package that exists at version v2.0.0 of the github.com/DataDog/dd-trace-go/v2 module. (The contrib directory at least at that version does not have a go.mod itself, so it's part of the github.com/DataDog/dd-trace-go/v2 module).
  2. github.com/DataDog/dd-trace-go/v2/contrib/net/http is a separate Go module that has already been published. For example:
    • https://github.com/DataDog/dd-trace-go/blob/1bc2693d308286e2d062507833d9a5837cdb26c6/v2/contrib/net/http/go.mod
  3. So both github.com/DataDog/dd-trace-go/v2 and github.com/DataDog/dd-trace-go/v2/contrib/net/http exist as two separate modules, and separate modules are essentially versioned independently.
  4. pkg.go.dev tries to help people discover related modules (one of it's working names while it was being developed was the "discovery site"), so it might be reasonable that it is showing a relationship between those two modules on the https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2@v2.0.0/contrib page.
  5. If you as a module author want pkg.go.dev to stop displaying older previously published modules, the primary tool is publishing retractions: https://go.dev/ref/mod#go-mod-file-retract (and a related excellent blog post by a well-known Go contributor is https://seankhliao.com/blog/12021-10-17-go-mod-retract/).

I didn't really look at the other items below contrib. Also, I'm trying to stop short of giving concrete advice, as that would require more poking around 😅.

In general, though, I'll mentioned that adding nested modules to a repository or carving out a nested module or otherwise moving go.mod files within a repo can be fairly tricky. There's an old comment from Russ:

For all but power users, you probably want to adopt the usual convention that one repo = one module. It’s important for long-term evolution of code storage options that a repo can contain multiple modules, but it’s almost certainly not something you want to do by default.

It very well might be warranted in your case though.

Finally, one other tool that is sometimes needed in those types of cases is to set up potentially circular dependencies, which is outlined in this older write-up at https://go.dev/wiki/Modules#faqs--multi-module-repositories, though I don't immediately see that would be needed here, and also that write-up pre-dates the retract directive and some other improvements that have reduced the cases where circular dependencies are needed.

Comment From: seankhliao

as I understand, the "directory" listing is only for modules which match the prefix, rather than having source trees in the same location

so you need github.com/DataDog/dd-trace-go/v2/contrib/net/http/v2

Comment From: darccio

Allow me to add a quick recap and additional context:

  1. What we expect is that the linked modules shown at https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2@v2.0.0/contrib target the corresponding module as defined in those nested modules. I.e.: /contrib/net/http should point to https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/net/http/v2@v2.0.0 (notice that /v2 is at the end, not in the middle of the URL)
  2. We took the decision of going "one repo = multiple modules" because of one usual issue for our enterprise customers, as we include instrumentation for multiple third party libraries, thus pulling lots of dependencies. Some security processes require that the go.mod and go.sum to be almost perfect - without considering that many of those dependencies are not compiled in the final binary.
  3. When we took that decision, we read and considered the different write-ups around multi-module repositories.
  4. At one point, we moved those contribs to /v2/contribs/, leading to the existing problem. That's what we see in this commit: https://github.com/DataDog/dd-trace-go/blob/1bc2693d308286e2d062507833d9a5837cdb26c6/v2/contrib/net/http/go.mod
  5. That was before we tagged the first version. At that moment we discovered that we had to move back from /v2/contribs to /contribs.
  6. The /contribs package itself was added later, when we realized it was empty - initially we didn't have any Go file there - so it's just a stub to generate the directory listing.
  7. We were under the impression that the directory listing would take into account the content of each nested module according to the tag and go.mod, but it seems to do the opposite: building the URL using the root module URL prefix and appending the path.

TL;DR: we would like to show at https://pkg.go.dev/github.com/DataDog/dd-trace-go/v2/contrib our list of nested modules - like https://pkg.go.dev/github.com/DataDog/dd-trace-go/contrib/net/http/v2 - at the current tag (latest or the one selected by the use).

Thanks, we really appreciate your effort and time.

Comment From: seankhliao

As I mentioned above, the listing is based on import path prefix, not source repository. The /v2 isn't just a cosmetic thing, it is a real part of your import path. You will need the double v2 in your import paths. If you had custom import paths, you would have been able to do some indirection with #34055 to not move your code around, but as it stands, you will need to move your code directories to achieve what you want.

Comment From: thepudds

Hi @hannahkm and @darccio, I wonder if it might make sense to think of it as two separate problems. As I understand it: 1. You don't want the old versions of the contrib modules showing up in the "Directories" section of the contrib doc page. 2. You do want the new versions of the contrib modules to be linked from the contrib doc page.

Maybe you can think about how to solve those somewhat independently. For example, no matter what else you do, you might want to issue retracts for the ~year old versions of the contrib modules, including because someone might otherwise stumble upon them (e.g., via a google search).

If you do retract, that might then cause those older versions to stop appearing in the "Directories" section of your latest contrib package, which might help issue 1.

For issue 2, part of the rationale for the richer Go doc comment formatting from proposal #51082 was to give package and module authors more control & more options for how things were rendered on pkg.go.dev. I wonder if it might be an ~80% solution if you did the linking yourself to your related modules via the contrib package doc, organized however you think best.

FWIW, I created a quick & dirty example repository with a top-level module and a few nested modules (4 total modules within a single repo), and then I took all 4 modules to v2.

Here is the top-level module's contrib package documentation, where I added some sample links to the related nested modules (without relying on pkg.go.dev to figure out the relationship):

https://pkg.go.dev/github.com/thepudds/nested-module-example/v2/contrib#hdr-Contrib_Modules

You'll note there's no "Directories" section shown for the contrib package at v2 (though there is a "Directories" section if you look at the v1 version, which has the same on-disk layout as v2).

That's not intended to be exactly the same pattern as your repo -- it's just a quick example, but you could of course try to create a more faithful test repo if you wanted to test things out before trying anything on your real repo.

In any event, maybe that's not exactly what you were hoping for, but it's maybe some more alternatives for you to consider or explore.

(Finally, I'm using "nested" a bit informally here -- I roughly mean a module that is rooted in a subdirectory of a repo while another module is rooted in a higher-level directory of the same repo).