hashicorp/terraform · warning

Option -write cannot be used when reading from stdin

Error message

Option -write cannot be used when reading from stdin

What it means

Returned by FmtCommand.fmt (fmt.go:115) when paths is empty (stdin mode) and the -write flag is still true. When fmt reads from stdin it cannot write back to a source file, so -write is meaningless; the Run method already disables write when args[0] == "-", but this check catches the case where the user explicitly forces -write=true with stdin input. It is a precondition failure surfaced as a diagnostic.

Source

Thrown at internal/command/fmt.go:120

		if list {
			io.Copy(&cli.UiWriter{Ui: c.Ui}, buf)
		}
		if ok {
			return 0
		} else {
			return 3
		}
	}

	return 0
}

func (c *FmtCommand) fmt(paths []string, stdin io.Reader, stdout io.Writer) tfdiags.Diagnostics {
	var diags tfdiags.Diagnostics

	if len(paths) == 0 { // Assuming stdin, then.
		if c.write {
			diags = diags.Append(fmt.Errorf("Option -write cannot be used when reading from stdin"))
			return diags
		}
		fileDiags := c.processFile("<stdin>", stdin, stdout, true)
		diags = diags.Append(fileDiags)
		return diags
	}

	for _, path := range paths {
		path = c.normalizePath(path)
		info, err := os.Stat(path)
		if err != nil {
			diags = diags.Append(fmt.Errorf("No file or directory at %s", path))
			return diags
		}
		if info.IsDir() {
			dirDiags := c.processDir(path, stdout)
			diags = diags.Append(dirDiags)
		} else {

View on GitHub (pinned to c9def3e214)

Solutions

  1. Drop the -write flag when reading from stdin: `terraform fmt -` (write is auto-disabled for stdin).
  2. Explicitly disable it: `terraform fmt -write=false -`.
  3. If you want to write formatted output to a file from stdin, redirect stdout: `terraform fmt - < in.tf > out.tf`.
  4. For files/directories, keep -write (the default) — the error only applies to stdin.

Example fix

# before
echo 'resource "x" "y"{}' | terraform fmt -write=true -
# Option -write cannot be used when reading from stdin

# after
echo 'resource "x" "y"{}' | terraform fmt -
Defensive patterns

Strategy: validation

Validate before calling

// Clear -write automatically when the target is stdin
isStdin := len(paths) == 0 || (len(args) > 0 && args[0] == stdinArg)
if isStdin && c.write {
    c.write = false
}

Prevention

When it happens

Trigger: Invoking `terraform fmt -write=true -` (explicit write with stdin marker), or piping input while keeping the default -write=true behavior in a code path that does not pre-clear it. The Run method auto-disables write for stdin, so this fires mainly when -write is explicitly set after the auto-disable.

Common situations: Piping HCL into fmt with `-write` left on: `cat main.tf | terraform fmt -write=true -`; a wrapper script that always passes -write=true; copy-paste of a fmt invocation that worked on files but now targets stdin.

Related errors


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