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

  1. Replace the '*' glob with the exact subdirectory name that contains the module.
  2. Repackage the archive so its root contains a single top-level directory.
  3. 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

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


AI-assisted analysis of hashicorp/terraform@c9def3e214 (2026-08-07). Data as JSON: /api/errors/b596a85b4b69ce06. Report an issue: GitHub.