Skip to content

cmd/go: doc: "go doc pkg.Func" doesn't search in defining package whose path has form "example.com/pkg-go/v2" #76248

Open

Description

@northbear

Proposal Details

Issue Description
The go doc command is a core Go tool designed to extract and display documentation comments for packages, symbols (e.g., functions, types, constants, variables), methods, or fields directly from the command line. It is particularly useful for quick lookups during development without needing to open a browser or IDE. However, its current behavior creates friction when working with imported external modules, which is a common workflow in modern Go projects using the module system.

Core Problem
Default Behavior: When invoked without a fully qualified path (e.g., go doc openai.NewClient), go doc assumes the symbol (e.g., openai.NewClient) exists in the current package (the directory where the command is run). It searches locally and fails if the symbol is not defined there.
Error: doc: symbol openai is not a type in package main installed in "." (or similar, indicating a local lookup failure).

Root Cause: Imported packages (e.g., via import "github.com/openai/openai-go/v3") are aliased in your code (often as openai), but go doc does not automatically resolve or infer these import paths from your source files or go.mod. It requires the full import path (e.g., go doc github.com/openai/openai-go/v3.NewClient) to locate and display docs from external modules.
User Impact:
Developers must manually recall or copy-paste full import paths, which are often long and verbose (e.g., github.com/openai/openai-go/v3.option.WithAPIKey).
This disrupts quick iteration, especially in large projects with many dependencies.
It feels unintuitive compared to code editors/IDEs (e.g., VS Code with gopls), which resolve imports contextually and show hover docs seamlessly.
No built-in way to discover or list imported symbols from the current workspace without additional tools like go list or godoc.

This issue stems from the tool's design philosophy: it's lightweight and package-centric, prioritizing simplicity over deep workspace awareness. From Go's official docs (cmd/doc package):
"The first argument must be a full package path."
While effective for stdlib or local packages, it underperforms for the module-heavy ecosystem introduced in Go 1.11.

Reproducibility
Create a minimal main.go importing an external module (e.g., OpenAI's Go client).
Run go mod tidy to fetch dependencies.
Execute go doc → Fails with local package error.
Use full path → Succeeds, but requires extra effort.

This affects ~80-90% of real-world Go usage, where projects import 5+ external modules on average (based on common go.mod patterns).

Proposal
Make go doc <symbol> automatically resolve symbols from imported packages in the current directory if not found locally.

Activity

  1. added this to the Proposal milestone on Nov 11, 2025
  2. changed the title [-]proposal: import/path: proposal title[/-] [+]proposal: Provide go doc documentation by imported package symbol instead of it full path[/+] on Nov 11, 2025
  3. adonovan commented on Nov 11, 2025

    @adonovan
    Member

    Does it not do this already? For example, in golang.org/x/tools:

    # The go.work file means we needn't "cd gopls".
    tools$ cat go.work
    go 1.25
    use .
    use ./gopls
    
    # list some external dependencies of gopls
    tools$ go list -deps ./gopls/ | grep [.] | grep -v golang.org | head 
    crypto/internal/entropy/v1.0.0
    honnef.co/go/tools/analysis/facts/tokenfile
    honnef.co/go/tools/analysis/lint
    honnef.co/go/tools/analysis/facts/generated
    honnef.co/go/tools/go/ast/astutil
    honnef.co/go/tools/go/types/typeutil
    honnef.co/go/tools/go/ir
    honnef.co/go/tools/go/ir/irutil
    honnef.co/go/tools/internal/passes/buildir
    honnef.co/go/tools/analysis/facts/purity
    ...
    
    # Show documentation for one of them by full path
    tools$ go doc honnef.co/go/tools/go/ir/irutil
    package irutil // import "honnef.co/go/tools/go/ir/irutil"
    
    func AllFunctions(prog *ir.Program) map[*ir.Function]bool
    ...
    
    
    # Show documentation for one of its symbols by short pkg.Name form
    tools$ go doc irutil.AllFunctions
    package irutil // import "honnef.co/go/tools/go/ir/irutil"
    
    func AllFunctions(prog *ir.Program) map[*ir.Function]bool
        AllFunctions finds and returns the set of functions potentially needed by
        program prog, as determined by a simple linker-style reachability algorithm
        starting from the members and method-sets of each package. The result may
        include anonymous functions and synthetic wrappers.
    ...
    
  4. added
    WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.
    on Nov 11, 2025
  5. northbear commented on Nov 12, 2025

    @northbear
    Author

    @adonovan
    For me it works this way:

    [space@micron-l2 learn-openai]$ ls
    go.mod  go.sum  main.go
    [space@micron-l2 learn-openai]$ cat go.mod
    module learn-openai
    
    go 1.25.3
    
    require github.com/openai/openai-go/v3 v3.8.1
    
    require (
    	github.com/tidwall/gjson v1.14.4 // indirect
    	github.com/tidwall/match v1.1.1 // indirect
    	github.com/tidwall/pretty v1.2.1 // indirect
    	github.com/tidwall/sjson v1.2.5 // indirect
    )
    [space@micron-l2 learn-openai]$ head -20 main.go 
    package main
    
    import (
    	"context"
    	"fmt"
    
    	"github.com/openai/openai-go/v3"
    	"github.com/openai/openai-go/v3/option"
    )
    
    func main() {
    	client := openai.NewClient(
    		option.WithAPIKey("My API Key"), // or set OPENAI_API_KEY in your env
    	)
    
    	resp, err := client.Responses.New(context.TODO(), openai.ResponseNewParams{
    		Model: openai.F("gpt-5"),
    		Input: openai.F("Say this is a test"),
    	})
    	if err != nil {
    [space@micron-l2 learn-openai]$ 
    [space@micron-l2 learn-openai]$ go doc github.com/openai/openai-go/v3.NewClient
    package openai // import "github.com/openai/openai-go/v3"
    
    func NewClient(opts ...option.RequestOption) (r Client)
        NewClient generates a new client with the default option read from
        the environment (OPENAI_API_KEY, OPENAI_ORG_ID, OPENAI_PROJECT_ID,
        OPENAI_WEBHOOK_SECRET, OPENAI_BASE_URL). The option passed in as arguments
        are applied after these default arguments, and all option will be passed
        down to the services and requests that this client makes.
    
    [space@micron-l2 learn-openai]$ 
    [space@micron-l2 learn-openai]$ go doc openai.NewClient
    doc: symbol openai is not a type in package main installed in "."
    [space@micron-l2 learn-openai]$ 
    [space@micron-l2 learn-openai]$ go version
    go version go1.25.3 X:nodwarf5 linux/amd64
    [space@micron-l2 learn-openai]$ 
    

    I wonder how it works in your case. I can get doc by a symbol only for Go stdlib stuff and local application. For imported packages I have to specify full path all the time.

  6. adonovan commented on Nov 12, 2025

    @adonovan
    Member

    Ah, thanks for clarifying. It looks like the discrepancy between the package name (openai) and the package path (.../openai-go/v3) might be the origin of the problem, either because of the final version segment, or the -go suffix.

    I'm going to recategorize this as a bug in the existing implementation.

  7. added
    BugReportIssues describing a possible bug in the Go implementation.
    and removed
    WaitingForInfoIssue is not actionable because of missing required information, which needs to be provided.
    on Nov 12, 2025
  8. modified the milestones: Proposal, Unplanned on Nov 12, 2025
  9. changed the title [-]proposal: Provide go doc documentation by imported package symbol instead of it full path[/-] [+]cmd/go: doc: "go doc pkg.Func" doesn't search in defining package path of form "example.com/pkg-go/v2"[/+] on Nov 12, 2025
  10. changed the title [-]cmd/go: doc: "go doc pkg.Func" doesn't search in defining package path of form "example.com/pkg-go/v2"[/-] [+]cmd/go: doc: "go doc pkg.Func" doesn't search in defining package whose path has form "example.com/pkg-go/v2"[/+] on Nov 12, 2025
  11. adonovan commented on Nov 12, 2025

    @adonovan
    Member
  12. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Nov 12, 2025
  13. seankhliao commented on Nov 12, 2025

    @seankhliao
    Member

    Is this a dupe of #41501 ?

  14. adonovan commented on Nov 12, 2025

    @adonovan
    Member

    Quite possibly, though only an experiment will confirm.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.DocumentationIssues describing a change to documentation.GoCommandcmd/goNeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.

    Type

    No type

    Projects

    No projects

      Milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions