{"record":{"id":"b596a85b4b69ce06","repo":"hashicorp/terraform","slug":"subdir-q-matches-multiple-paths","errorCode":null,"errorMessage":"subdir %q matches multiple paths","messagePattern":"subdir %q matches multiple paths","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/subdir.go","lineNumber":93,"sourceCode":"// to select the contents of the single directory at the root of a conventional\n// tar archive but it doesn't actually know the exact name of that directory.\n// In that case it might specify a subdir of just \"*\", which this function\n// will then expand into the single subdirectory found inside instDir, or\n// return an error if the result would be ambiguous.\nfunc ExpandSubdirGlobs(instDir string, subDir string) (string, error) {\n\tpattern := filepath.Join(instDir, subDir)\n\n\tmatches, err := filepath.Glob(pattern)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\n\tif len(matches) == 0 {\n\t\treturn \"\", fmt.Errorf(\"subdir %q not found\", subDir)\n\t}\n\n\tif len(matches) > 1 {\n\t\treturn \"\", fmt.Errorf(\"subdir %q matches multiple paths\", subDir)\n\t}\n\n\treturn matches[0], nil\n}\n","sourceCodeStart":75,"sourceCodeEnd":98,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/subdir.go#L75-L98","documentation":"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.","triggerScenarios":"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.","commonSituations":"A repackaged or vendor-supplied archive with extra directories; accidental inclusion of __MACOSX or metadata folders; non-standard registry packaging.","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."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Detect ambiguous globs before relying on ExpandSubdirGlobs.\nfunc uniqueGlobMatch(instDir, subDir string) (string, error) {\n\tmatches, err := filepath.Glob(filepath.Join(instDir, subDir))\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif len(matches) > 1 {\n\t\treturn \"\", fmt.Errorf(\"subdir %q is ambiguous: %v\", subDir, matches)\n\t}\n\tif len(matches) == 0 {\n\t\treturn \"\", fmt.Errorf(\"subdir %q not found\", subDir)\n\t}\n\treturn matches[0], nil\n}","typeGuard":null,"tryCatchPattern":"resolved, err := moduleaddrs.ExpandSubdirGlobs(instDir, subDir)\nif err != nil && strings.Contains(err.Error(), \"matches multiple paths\") {\n    // Disambiguate by naming the exact directory.\n    return moduleaddrs.ExpandSubdirGlobs(instDir, exactSubDir)\n}","preventionTips":["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."],"tags":["module-source","subdir","filesystem","registry"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}