hashicorp/terraform · error

There is no configuration directory at

Error message

There is no configuration directory at %s

What it means

Thrown by processDir when os.ReadDir returns an error matching os.IsNotExist — the target directory path does not exist on disk. Used during recursive directory processing in `terraform fmt`.

Solutions

  1. Verify the directory exists: `ls -ld <path>`.
  2. Check for typos and correct the path argument.
  3. If using a symlink, ensure its target exists (`readlink -f <path>`).
Defensive patterns

Strategy: validation

Validate before calling

// Verify a directory exists before passing it to fmt.
func dirExists(p string) bool {
    fi, err := os.Stat(p)
    return err == nil && fi.IsDir()
}

Prevention

When it happens

Trigger: Passing a directory path that does not exist; a subdirectory removed between stat and readdir; typo in the path argument; running fmt from the wrong working directory.

Common situations: Typo'd module path; running `terraform fmt ./mymodule` from a parent dir where ./mymodule does not exist; path with a stale symlink pointing to a removed target.

Related errors


AI-assisted analysis of hashicorp/terraform@d32a084675 (2026-08-11). Data as JSON: /api/errors/757e8d7d5a1d51a4. Report an issue: GitHub.

Appendix: source

Thrown at internal/command/fmt.go:239

		_, err = w.Write(result)
		if err != nil {
			diags = diags.Append(fmt.Errorf("Failed to write result"))
		}
	}

	return diags
}

func (c *FmtCommand) processDir(path string, stdout io.Writer) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	log.Printf("[TRACE] terraform fmt: looking for files in %s", path)

	entries, err := os.ReadDir(path)
	if err != nil {
		switch {
		case os.IsNotExist(err):
			diags = diags.Append(fmt.Errorf("There is no configuration directory at %s", path))
		default:
			// ReadDir does not produce error messages that are end-user-appropriate,
			// so we'll need to simplify here.
			diags = diags.Append(fmt.Errorf("Cannot read directory %s", path))
		}
		return diags
	}

	for _, info := range entries {
		name := info.Name()
		if configs.IsIgnoredFile(name) {
			continue
		}
		subPath := filepath.Join(path, name)
		if info.IsDir() {
			if c.recursive {
				subDiags := c.processDir(subPath, stdout)
				diags = diags.Append(subDiags)

View on GitHub (pinned to d32a084675)