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

  1. Replace the wildcard with the concrete subdir path you want.
  2. Pin the module ref to a version whose archive has a single top-level directory.
  3. 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

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


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)