hashicorp/terraform · error
subdir matches multiple paths
Error message
subdir %q matches multiple paths
What it means
Returned by ExpandSubdirGlobs when filepath.Glob of instDir/subDir yields more than one match. The wildcard '*' is meant to collapse a single nested directory automatically; multiple matches make the choice ambiguous, so the function refuses to guess. The %q is the subdir pattern.
Solutions
- Replace the wildcard with the concrete subdir path you want.
- Pin the module ref to a version whose archive has a single top-level directory.
- Re-package the source so the wildcard is unambiguous.
Example fix
# before (multiple top-level dirs -> ambiguous) source = "github.com/org/repo//*" # after (concrete subdir) source = "github.com/org/repo//modules/vpc"
Defensive patterns
Strategy: validation
Validate before calling
// Detect ambiguous wildcards before expansion.
// matches, _ := filepath.Glob(filepath.Join(instDir, subDir))
// if len(matches) > 1 {
// return fmt.Errorf("subdir %q is ambiguous: %v", subDir, matches)
// } Prevention
- Avoid '*' in subdirs; specify concrete paths.
- Pin module refs whose archives have a single top-level directory.
- Re-package archives to remove top-level ambiguity.
When it happens
Trigger: A subdir pattern containing '*' (or matching multiple entries) resolves to several directories inside the extracted package, e.g. an archive with several top-level folders when the source expected exactly one.
Common situations: Module archive ships multiple top-level directories; ref changed to one with a different layout; wildcard used where a concrete path should be.
Related errors
- subdir not found
- archive has incorrect checksum
- cannot check archive hash for non-archive location
- detected subdirectory path
- Error parsing URL
AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11).
Data as JSON: /api/errors/b596a85b4b69ce06.
Report an issue: GitHub.
Appendix: 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 d32a084675)