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
- Provide a non-empty script path string, or switch to `scripts` / `inline` if you have multiple commands.
- 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
- Use `script` only with a concrete non-empty path.
- Prefer `scripts`/`inline` for multi-command cases.
- Guard the resource with count when the script value is conditional.
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
- invalid empty string in 'scripts'
- invalid null string in 'script'
- invalid null string in 'scripts'
- Cannot set both 'source' and 'content'
- host for provisioner cannot be empty
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 scriptsView on GitHub (pinned to d32a084675)