{"record":{"id":"d74e925e5a374043","repo":"hashicorp/terraform","slug":"invalid-null-string-in-script","errorCode":null,"errorMessage":"invalid null string in 'script'","messagePattern":"invalid null string in 'script'","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"internal/builtin/provisioners/remote-exec/resource_provisioner.go","lineNumber":203,"sourceCode":"\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\n\tvar fhs []io.ReadCloser\n\tfor _, s := range scripts {\n\t\tfh, err := os.Open(s)\n\t\tif err != nil {\n\t\t\tfor _, fh := range fhs {\n\t\t\t\tfh.Close()\n\t\t\t}\n\t\t\treturn nil, fmt.Errorf(\"Failed to open script '%s': %v\", s, err)","sourceCodeStart":185,"sourceCodeEnd":221,"githubUrl":"https://github.com/hashicorp/terraform/blob/d32a084675427f5ac3f7d2868578ef8b2c1dc525/internal/builtin/provisioners/remote-exec/resource_provisioner.go#L185-L221","documentation":"Thrown by remote-exec collectScripts (resource_provisioner.go:203) when iterating the plural `scripts` list: if any element is null, the provisioner rejects it. `scripts` expects a list of concrete file-path strings; a null entry has no file to open.","triggerScenarios":"A provisioner \"remote-exec\" block with `scripts = [var.maybe_null_path, \"./2.sh\"]` where one element is null at apply time.","commonSituations":"scripts list assembled from variables where one entry is conditionally null.","solutions":["Filter nulls from the scripts list, e.g. `scripts = [for s in var.paths : s if s != null]`.","Give every element a concrete file path string."],"exampleFix":"# before\nvariable \"paths\" { type = list(string) }\nprovisioner \"remote-exec\" {\n  scripts = var.paths\n}\n# after\nvariable \"paths\" { type = list(string) }\nprovisioner \"remote-exec\" {\n  scripts = [for s in var.paths : s if s != null]\n}","handlingStrategy":"validation","validationCode":"func scriptsHaveNoNull(paths []any) error {\n    for _, p := range paths {\n        if p == nil { return errors.New(\"invalid null string in 'script'\") }\n    }\n    return nil\n}","typeGuard":"func scriptsNoNull(v cty.Value) bool {\n    for _, e := range v.AsValueSlice() {\n        if e.IsNull() { return false }\n    }\n    return true\n}","tryCatchPattern":null,"preventionTips":["Filter nulls: [for s in paths : s if s != null].","Type the supplying variable as set(string)/list(string)."],"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"}