{"record":{"id":"57a2623a86fb5f63","repo":"golang/go","slug":"internal-error-matchpackages-s-is-not-a-valid-p","errorCode":null,"errorMessage":"internal error: MatchPackages: %s is not a valid package pattern","messagePattern":"internal error: MatchPackages: (.+?) is not a valid package pattern","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/search/search.go","lineNumber":106,"sourceCode":"\t}\n\treturn fmt.Sprintf(\"pattern %s: %v\", e.Match.Pattern(), e.Err)\n}\n\nfunc (e *MatchError) Unwrap() error {\n\treturn e.Err\n}\n\n// MatchPackages sets m.Pkgs to a non-nil slice containing all the packages that\n// can be found under the $GOPATH directories and $GOROOT that match the\n// pattern. The pattern must be either \"all\" (all packages), \"std\" (standard\n// packages), \"cmd\" (standard commands), or a path including \"...\".\n//\n// If any errors may have caused the set of packages to be incomplete,\n// MatchPackages appends those errors to m.Errs.\nfunc (m *Match) MatchPackages() {\n\tm.Pkgs = []string{}\n\tif m.IsLocal() {\n\t\tm.AddError(fmt.Errorf(\"internal error: MatchPackages: %s is not a valid package pattern\", m.pattern))\n\t\treturn\n\t}\n\n\tif m.IsLiteral() {\n\t\tm.Pkgs = []string{m.pattern}\n\t\treturn\n\t}\n\n\tmatch := func(string) bool { return true }\n\ttreeCanMatch := func(string) bool { return true }\n\tif !m.IsMeta() {\n\t\tmatch = pkgpattern.MatchPattern(m.pattern)\n\t\ttreeCanMatch = pkgpattern.TreeCanMatchPattern(m.pattern)\n\t}\n\n\thave := map[string]bool{\n\t\t\"builtin\": true, // ignore pseudo-package that exists only for documentation\n\t}","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/search/search.go#L88-L124","documentation":"Internal error added to a Match via MatchPackages when the match's pattern is a local/filesystem pattern (IsLocal() true). MatchPackages only handles non-local patterns ('all', 'std', 'cmd', or '...' import-path patterns), so a local pattern reaching it means the wrong matcher was dispatched — a programming error in the caller, not a user config issue.","triggerScenarios":"Calling search.Match.MatchPackages() on a Match constructed with a local pattern such as './pkg' or an absolute path — the dispatcher that should have routed to MatchDirs misrouted instead.","commonSituations":"Seen only in tooling/tests that drive search.Match directly with a local pattern via the wrong method; not produced by the standard CLI invocation paths.","solutions":["If you call search.Match directly, route local patterns to MatchDirs, not MatchPackages.","Use search.NewMatch + the correct matcher by checking m.IsLocal() first.","Report as a Go toolchain bug if it surfaces from a normal 'go' command."],"exampleFix":"// before\nm := search.NewMatch(\"./pkg\")\nm.MatchPackages() // error: internal error: MatchPackages: ./pkg is not a valid package pattern\n\n// after\nm := search.NewMatch(\"./pkg\")\nm.MatchDirs(modRoots) // correct matcher for local patterns","handlingStrategy":"type-guard","validationCode":"// Route by pattern locality before matching:\n//   if m.IsLocal() { m.MatchDirs(modRoots) } else { m.MatchPackages() }","typeGuard":"func matchCorrectly(m *search.Match, modRoots []string) {\n    if m.IsLocal() {\n        m.MatchDirs(modRoots)\n    } else {\n        m.MatchPackages()\n    }\n}","tryCatchPattern":null,"preventionTips":["Always check IsLocal() before choosing MatchPackages vs MatchDirs.","In tests driving search.Match, assert the right matcher is dispatched.","Report CLI occurrences as a toolchain bug."],"tags":["go-modules","internal-error","search","patterns"],"backgroundTag":null,"analyzedSha":"b6b368adc57c96c3151d224d172029f233ead2c3","analyzedAt":"2026-08-12T00:22:02.250Z","schemaVersion":2},"datasetVersion":"2026-08-12T12:31:55.035Z"}