{"record":{"id":"57ad0588c27a7f0e","repo":"hashicorp/terraform","slug":"invalid-empty-string-in-script","errorCode":null,"errorMessage":"invalid empty string in 'script'","messagePattern":"invalid empty string in 'script'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/provisioners/remote-exec/resource_provisioner.go","lineNumber":195,"sourceCode":"\t\tscripts, err := generateScripts(inline)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\n\t\tvar r []io.ReadCloser\n\t\tfor _, script := range scripts {\n\t\t\tr = append(r, io.NopCloser(bytes.NewReader([]byte(script))))\n\t\t}\n\n\t\treturn r, nil\n\t}\n\n\t// Collect scripts\n\tvar scripts []string\n\tif script := v.GetAttr(\"script\"); !script.IsNull() {\n\t\ts := script.AsString()\n\t\tif s == \"\" {\n\t\t\treturn nil, errors.New(\"invalid empty string in 'script'\")\n\t\t}\n\t\tscripts = append(scripts, s)\n\t}\n\n\tif scriptList := v.GetAttr(\"scripts\"); !scriptList.IsNull() {\n\t\tfor _, script := range scriptList.AsValueSlice() {\n\t\t\tif script.IsNull() {\n\t\t\t\treturn nil, errors.New(\"invalid null string in 'script'\")\n\t\t\t}\n\t\t\ts := script.AsString()\n\t\t\tif s == \"\" {\n\t\t\t\treturn nil, errors.New(\"invalid empty string in 'script'\")\n\t\t\t}\n\t\t\tscripts = append(scripts, s)\n\t\t}\n\t}\n\n\t// Open all the scripts","sourceCodeStart":177,"sourceCodeEnd":213,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/builtin/provisioners/remote-exec/resource_provisioner.go#L177-L213","documentation":"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.","triggerScenarios":"A provisioner \"remote-exec\" block with `script = \"\"` (or a variable resolving to \"\") — collectScripts reads script.AsString(), finds it empty, and returns the error.","commonSituations":"A `script` argument sourced from a variable/local that defaults to or evaluates to \"\".","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)."],"exampleFix":"# before\nvariable \"s\" { type = string }\nprovisioner \"remote-exec\" {\n  script = var.s   # resolves to \"\"\n}\n# after\nprovisioner \"remote-exec\" {\n  inline = [\"echo done\"]\n}","handlingStrategy":"validation","validationCode":"func validateSingleScript(s string) error {\n    if s == \"\" { return errors.New(\"invalid empty string in 'script'\") }\n    return nil\n}","typeGuard":"func nonEmptyScript(v cty.Value) bool {\n    return v.IsNull() || v.AsString() != \"\"\n}","tryCatchPattern":null,"preventionTips":["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."],"tags":["terraform","provisioner","remote-exec","validation","config"],"backgroundTag":null,"analyzedSha":"d32a084675427f5ac3f7d2868578ef8b2c1dc525","analyzedAt":"2026-08-11T18:43:52.779Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}