{"record":{"id":"7064cdead3eaac2b","repo":"hashicorp/terraform","slug":"subdir-q-not-found","errorCode":null,"errorMessage":"subdir %q not found","messagePattern":"subdir %q not found","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/getmodules/moduleaddrs/subdir.go","lineNumber":89,"sourceCode":"// files on disk in the given directory which we assume contains the content\n// of whichever package this is a subdirectory glob for.\n//\n// Subdir globs are used, for example, when a module registry wants to specify\n// 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":71,"sourceCodeEnd":98,"githubUrl":"https://github.com/hashicorp/terraform/blob/c9def3e214014c1188faabfc4a5bde5095139765/internal/getmodules/moduleaddrs/subdir.go#L71-L98","documentation":"Raised by ExpandSubdirGlobs (internal/getmodules/moduleaddrs/subdir.go:89). This function expands a (possibly glob) subdir pattern against a real installed directory, typically after a registry-served archive is extracted. If filepath.Glob returns zero matches, the expected subdirectory is not present on disk.","triggerScenarios":"A registry module whose subdir spec (often '*') finds no top-level directory in the extracted archive, or a named subdir that does not exist, e.g. an archive whose contents sit at the root rather than inside a single directory.","commonSituations":"Non-standard archive layout (files at root instead of one wrapping directory); a typo'd subdir name in the source address; a partially extracted or corrupt cache; a registry returning an archive packed differently than expected.","solutions":["Clear the module cache and re-download/extract so the archive layout matches expectations.","Verify the archive structure (it should contain a single top-level directory when the subdir is '*').","Correct the subdir name in the source address to match a directory that actually exists in the package.","If you control the publishing, repackage the module so the root contains exactly one directory."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// Verify the expected subdir resolves before calling ExpandSubdirGlobs.\nfunc subdirExists(instDir, subDir string) (string, error) {\n\tpattern := filepath.Join(instDir, subDir)\n\tmatches, err := filepath.Glob(pattern)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\tif len(matches) == 0 {\n\t\treturn \"\", fmt.Errorf(\"subdir %q not found under %s\", subDir, instDir)\n\t}\n\treturn matches[0], nil\n}","typeGuard":null,"tryCatchPattern":"resolved, err := moduleaddrs.ExpandSubdirGlobs(instDir, subDir)\nif err != nil {\n    return fmt.Errorf(\"cannot resolve module subdir %q in %s: %w\", subDir, instDir, err)\n}","preventionTips":["Ensure module archives contain the expected directory layout (single top-level dir for '*').","Clear and re-extract the module cache if the layout is unexpected.","Use explicit subdir names rather than globs when the layout is known."],"tags":["module-source","subdir","filesystem","registry"],"analyzedSha":"c9def3e214014c1188faabfc4a5bde5095139765","analyzedAt":"2026-08-07T15:39:49.278Z","schemaVersion":2},"datasetVersion":"2026-08-07T20:17:04.800Z"}