{"record":{"id":"b277c0b25bce86a0","repo":"golang/go","slug":"internal-error-matchdirs-s-is-not-a-valid-files","errorCode":null,"errorMessage":"internal error: MatchDirs: %s is not a valid filesystem pattern","messagePattern":"internal error: MatchDirs: (.+?) is not a valid filesystem pattern","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/cmd/go/internal/search/search.go","lineNumber":289,"sourceCode":"\t\tpath = \"/\" + path\n\t}\n\tif !strings.HasSuffix(path, \"/\") {\n\t\tpath += \"/\"\n\t}\n\treturn path\n}\n\n// MatchDirs sets m.Dirs to a non-nil slice containing all directories that\n// potentially match a local pattern. The pattern must begin with an absolute\n// path, or \"./\", or \"../\". On Windows, the pattern may use slash or backslash\n// separators or a mix of both.\n//\n// If any errors may have caused the set of directories to be incomplete,\n// MatchDirs appends those errors to m.Errs.\nfunc (m *Match) MatchDirs(modRoots []string) {\n\tm.Dirs = []string{}\n\tif !m.IsLocal() {\n\t\tm.AddError(fmt.Errorf(\"internal error: MatchDirs: %s is not a valid filesystem pattern\", m.pattern))\n\t\treturn\n\t}\n\n\tif m.IsLiteral() {\n\t\tm.Dirs = []string{m.pattern}\n\t\treturn\n\t}\n\n\t// Clean the path and create a matching predicate.\n\t// filepath.Clean removes \"./\" prefixes (and \".\\\" on Windows). We need to\n\t// preserve these, since they are meaningful in MatchPattern and in\n\t// returned import paths.\n\tcleanPattern := filepath.Clean(m.pattern)\n\tisLocal := strings.HasPrefix(m.pattern, \"./\") || (os.PathSeparator == '\\\\' && strings.HasPrefix(m.pattern, `.\\`))\n\tprefix := \"\"\n\tif cleanPattern != \".\" && isLocal {\n\t\tprefix = \"./\"\n\t\tcleanPattern = \".\" + string(os.PathSeparator) + cleanPattern","sourceCodeStart":271,"sourceCodeEnd":307,"githubUrl":"https://github.com/golang/go/blob/b6b368adc57c96c3151d224d172029f233ead2c3/src/cmd/go/internal/search/search.go#L271-L307","documentation":"Internal error added to a Match via MatchDirs when the match's pattern is NOT a local/filesystem pattern (IsLocal() false). MatchDirs requires a pattern starting with an absolute path, './', or '../'; any other pattern reaching it indicates the dispatcher misrouted a non-local pattern to the filesystem matcher.","triggerScenarios":"Calling search.Match.MatchDirs() on a Match whose pattern is an import-path pattern like 'example.com/pkg' or 'all' — the dispatcher that should have routed to MatchPackages misrouted instead.","commonSituations":"Only in tooling/tests that drive search.Match with the wrong matcher for a non-local pattern; not produced by standard CLI paths.","solutions":["Route non-local patterns to MatchPackages, keeping MatchDirs for local patterns.","Guard the dispatch with m.IsLocal() before calling MatchDirs.","Report as a Go toolchain bug if encountered via a normal 'go' command."],"exampleFix":"// before\nm := search.NewMatch(\"example.com/pkg\")\nm.MatchDirs(modRoots) // error: internal error: MatchDirs: example.com/pkg is not a valid filesystem pattern\n\n// after\nm := search.NewMatch(\"example.com/pkg\")\nm.MatchPackages() // correct matcher for non-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 MatchDirs vs MatchPackages.","Never call MatchDirs on import-path patterns like 'all', 'std', or 'example.com/...'.","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"}