{"record":{"id":"e6961ec917ae0246","repo":"hashicorp/terraform","slug":"unable-to-locate-module-s","errorCode":null,"errorMessage":"unable to locate module: %s","messagePattern":"unable to locate module: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/command/validate.go","lineNumber":73,"sourceCode":"\n\tloader, err := c.initConfigLoader()\n\tif err != nil {\n\t\tdiags = diags.Append(err)\n\t\treturn view.Results(diags)\n\t}\n\n\tvar varDiags tfdiags.Diagnostics\n\tc.VariableValues, varDiags = args.Vars.CollectValues(func(filename string, src []byte) {\n\t\tloader.Parser().ForceFileSource(filename, src)\n\t})\n\tif varDiags.HasErrors() {\n\t\tdiags = diags.Append(varDiags)\n\t\treturn view.Results(diags)\n\t}\n\n\tdir, err := filepath.Abs(args.Path)\n\tif err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"unable to locate module: %s\", err))\n\t\treturn view.Results(diags)\n\t}\n\n\t// Check for user-supplied plugin path\n\tif c.pluginPath, err = c.loadPluginPath(); err != nil {\n\t\tdiags = diags.Append(fmt.Errorf(\"error loading plugin path: %s\", err))\n\t\treturn view.Results(diags)\n\t}\n\n\tvalidateDiags := c.validate(dir)\n\tdiags = diags.Append(validateDiags)\n\n\t// Validating with dev overrides in effect means that the result might\n\t// not be valid for a stable release, so we'll warn about that in case\n\t// the user is trying to use \"terraform validate\" as a sort of pre-flight\n\t// check before submitting a change.\n\tdiags = diags.Append(c.providerDevOverrideRuntimeWarnings())\n","sourceCodeStart":55,"sourceCodeEnd":91,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/command/validate.go#L55-L91","documentation":"Thrown by validate.go when filepath.Abs(args.Path) returns an error during `terraform validate`. filepath.Abs almost never errors — it only fails when os.Getwd fails (no current directory, e.g. the cwd was deleted out from under the process). Despite the message text 'unable to locate module', this is really a cwd-resolution failure, not a missing module.","triggerScenarios":"The shell's current working directory was removed or renamed while the terraform process is starting; filepath.Abs cannot resolve the relative args.Path because os.Getwd returns ENOENT.","commonSituations":"Running terraform from inside a directory that another process `rm -rf`'d; CI workspace wiped between checkout and terraform step; a wrapper that chdirs into a temp dir then deletes it; running in a container whose cwd mount was removed.","solutions":["Re-run from a directory that exists: `cd <existing-dir> && terraform validate`.","Pass an absolute path: `terraform validate /abs/path/to/module`.","In CI, ensure the workspace dir exists for the whole terraform invocation.","Check that the script did not delete its own cwd before invoking terraform."],"exampleFix":"# before\n cd /tmp/sandbox && rm -rf /tmp/sandbox && terraform validate\n\n# after\n cd /tmp/existing-dir\n terraform validate /abs/path/to/module","handlingStrategy":"validation","validationCode":"// Confirm cwd exists before calling validate.\nif _, err := os.Getwd(); err != nil {\n    return fmt.Errorf(\"current working directory is not accessible: %w\", err)\n}","typeGuard":null,"tryCatchPattern":"dir, err := filepath.Abs(args.Path)\nif err != nil {\n    diags = diags.Append(fmt.Errorf(\"unable to locate module (cwd may have been removed): %s\", err))\n    return view.Results(diags)\n}","preventionTips":["Invoke terraform from a stable, existing directory.","Pass an absolute path to `terraform validate /abs/path` in CI.","Do not delete the workspace dir mid-script.","Check `os.Getwd()` in wrappers before spawning terraform."],"tags":["terraform","validate","cwd","filesystem","paths"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}