{"record":{"id":"180b8d919a7becff","repo":"hashicorp/packer","slug":"either-a-script-file-or-inline-script-must-be-spec-180b8d","errorCode":null,"errorMessage":"Either a script file or inline script must be specified.","messagePattern":"Either a script file or inline script must be specified\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/windows-shell/provisioner.go","lineNumber":114,"sourceCode":"\t}\n\n\tif p.config.Vars == nil {\n\t\tp.config.Vars = make([]string, 0)\n\t}\n\n\tvar errs error\n\tif p.config.Script != \"\" && len(p.config.Scripts) > 0 {\n\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\terrors.New(\"Only one of script or scripts can be specified.\"))\n\t}\n\n\tif p.config.Script != \"\" {\n\t\tp.config.Scripts = []string{p.config.Script}\n\t}\n\n\tif len(p.config.Scripts) == 0 && p.config.Inline == nil {\n\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\terrors.New(\"Either a script file or inline script must be specified.\"))\n\t} else if len(p.config.Scripts) > 0 && p.config.Inline != nil {\n\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\terrors.New(\"Only a script file or an inline script can be specified, not both.\"))\n\t}\n\n\tfor _, path := range p.config.Scripts {\n\t\tif _, err := os.Stat(path); err != nil {\n\t\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\t\tfmt.Errorf(\"Bad script '%s': %s\", path, err))\n\t\t}\n\t}\n\n\t// Do a check for bad environment variables, such as '=foo', 'foobar'\n\tfor _, kv := range p.config.Vars {\n\t\tvs := strings.SplitN(kv, \"=\", 2)\n\t\tif len(vs) != 2 || vs[0] == \"\" {\n\t\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\t\tfmt.Errorf(\"Environment variable not in format 'key=value': %s\", kv))","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/windows-shell/provisioner.go#L96-L132","documentation":"Windows-shell provisioner equivalent of error 6: Prepare() requires either a script file or inline commands, and the config provided neither. With an empty scripts list and nil inline there is nothing to execute on the Windows guest, so validation fails.","triggerScenarios":"Prepare() on provisioner/windows-shell is called with len(p.config.Scripts) == 0 and p.config.Inline == nil — an empty windows-shell block, or a `script` value that resolved to an empty string via template variables.","commonSituations":"Empty windows-shell block scaffold left in the template; an HCL variable defaulting to \"\" used as `script`; users specifying only elevated/env options and forgetting the command source.","solutions":["Add `inline = [\"echo hello\"]` for inline commands.","Add `scripts = [\"./setup.ps1\"]` (or `script`) pointing at a .ps1/.bat/.cmd file.","Remove the windows-shell block if it is not needed."],"exampleFix":"// before\nprovisioner \"windows-shell\" {}\n// after\nprovisioner \"windows-shell\" {\n  scripts = [\"./setup.ps1\"]\n}","handlingStrategy":"validation","validationCode":"if len(cfg.Scripts) == 0 && cfg.Inline == nil {\n    return fmt.Errorf(\"windows-shell config: must set scripts, script, or inline\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never commit empty windows-shell blocks; remove or fill scaffolding.","Give template variables used as `script` non-empty defaults and validate them.","Run `packer validate` on templates in CI to catch missing command sources.","Call Prepare() in unit tests with the final resolved config, not just the raw template."],"tags":["packer","provisioner","config-validation","windows"],"backgroundTag":"missing-required-config","analyzedSha":"eb36e3c3e48a036f3e8cc94087636ee72e1303c9","analyzedAt":"2026-09-05T13:20:43.127Z","contentChangedAt":"2026-09-05T13:20:43.127Z","schemaVersion":2},"datasetVersion":"2026-09-12T17:17:11.597Z"}