hashicorp/terraform · error

invalid empty string in 'script'

Error message

invalid empty string in 'script'

What it means

Thrown by remote-exec collectScripts (resource_provisioner.go:195) for the single `script` attribute: if `script` is set but its string value is empty, the provisioner rejects it because there is no script content to run. This is the singular `script` (not `scripts`) attribute path.

Solutions

  1. Provide a non-empty script path string, or switch to `scripts` / `inline` if you have multiple commands.
  2. Guard with a conditional so the provisioner only runs when the script is non-empty (count = var.script != "" ? 1 : 0).

Example fix

# before
variable "s" { type = string }
provisioner "remote-exec" {
  script = var.s   # resolves to ""
}
# after
provisioner "remote-exec" {
  inline = ["echo done"]
}
Defensive patterns

Strategy: validation

Validate before calling

func validateSingleScript(s string) error {
    if s == "" { return errors.New("invalid empty string in 'script'") }
    return nil
}

Type guard

func nonEmptyScript(v cty.Value) bool {
    return v.IsNull() || v.AsString() != ""
}

Prevention

When it happens

Trigger: A provisioner "remote-exec" block with `script = ""` (or a variable resolving to "") — collectScripts reads script.AsString(), finds it empty, and returns the error.

Common situations: A `script` argument sourced from a variable/local that defaults to or evaluates to "".

Related errors


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

Appendix: source

Thrown at internal/builtin/provisioners/remote-exec/resource_provisioner.go:195

		scripts, err := generateScripts(inline)
		if err != nil {
			return nil, err
		}

		var r []io.ReadCloser
		for _, script := range scripts {
			r = append(r, io.NopCloser(bytes.NewReader([]byte(script))))
		}

		return r, nil
	}

	// Collect scripts
	var scripts []string
	if script := v.GetAttr("script"); !script.IsNull() {
		s := script.AsString()
		if s == "" {
			return nil, errors.New("invalid empty string in 'script'")
		}
		scripts = append(scripts, s)
	}

	if scriptList := v.GetAttr("scripts"); !scriptList.IsNull() {
		for _, script := range scriptList.AsValueSlice() {
			if script.IsNull() {
				return nil, errors.New("invalid null string in 'script'")
			}
			s := script.AsString()
			if s == "" {
				return nil, errors.New("invalid empty string in 'script'")
			}
			scripts = append(scripts, s)
		}
	}

	// Open all the scripts

View on GitHub (pinned to d32a084675)