hashicorp/terraform · error
subdir %q matches multiple paths
Error message
subdir %q matches multiple paths
What it means
Raised by ExpandSubdirGlobs (internal/getmodules/moduleaddrs/subdir.go:93). The glob pattern matched more than one path, making the subdirectory selection ambiguous. The function requires exactly one match (it is most commonly used with '*' to pick the single top-level directory of a tarball), so multiple matches are an error.
Source
Thrown at internal/getmodules/moduleaddrs/subdir.go:93
// to select the contents of the single directory at the root of a conventional
// tar archive but it doesn't actually know the exact name of that directory.
// In that case it might specify a subdir of just "*", which this function
// will then expand into the single subdirectory found inside instDir, or
// return an error if the result would be ambiguous.
func ExpandSubdirGlobs(instDir string, subDir string) (string, error) {
pattern := filepath.Join(instDir, subDir)
matches, err := filepath.Glob(pattern)
if err != nil {
return "", err
}
if len(matches) == 0 {
return "", fmt.Errorf("subdir %q not found", subDir)
}
if len(matches) > 1 {
return "", fmt.Errorf("subdir %q matches multiple paths", subDir)
}
return matches[0], nil
}
View on GitHub (pinned to c9def3e214)
Solutions
- Replace the '*' glob with the exact subdirectory name that contains the module.
- Repackage the archive so its root contains a single top-level directory.
- Remove extraneous top-level entries (e.g. __MACOSX, .github) from the archive root.
Defensive patterns
Strategy: validation
Validate before calling
// Detect ambiguous globs before relying on ExpandSubdirGlobs.
func uniqueGlobMatch(instDir, subDir string) (string, error) {
matches, err := filepath.Glob(filepath.Join(instDir, subDir))
if err != nil {
return "", err
}
if len(matches) > 1 {
return "", fmt.Errorf("subdir %q is ambiguous: %v", subDir, matches)
}
if len(matches) == 0 {
return "", fmt.Errorf("subdir %q not found", subDir)
}
return matches[0], nil
} Try / catch
resolved, err := moduleaddrs.ExpandSubdirGlobs(instDir, subDir)
if err != nil && strings.Contains(err.Error(), "matches multiple paths") {
// Disambiguate by naming the exact directory.
return moduleaddrs.ExpandSubdirGlobs(instDir, exactSubDir)
} Prevention
- Use exact subdir names instead of '*' when the layout is known.
- Repackage archives so the root holds exactly one directory.
- Remove stray top-level folders (e.g. __MACOSX) before publishing.
When it happens
Trigger: An extracted module archive whose root contains multiple top-level directories while the subdir spec is '*' (intended to match one), e.g. a tarball packed with several folders at the root.
Common situations: A repackaged or vendor-supplied archive with extra directories; accidental inclusion of __MACOSX or metadata folders; non-standard registry packaging.
Related errors
- subdir %q not found
- Error parsing URL: %s
- can't use local directory %q as a module registry address
- subdirectory path %q leads outside of the module package
- detected subdirectory path %q of %q leads outside of the mod
AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07).
Data as JSON: /api/errors/b596a85b4b69ce06.
Report an issue: GitHub.