{"record":{"id":"16b70cbc1071adf6","repo":"hashicorp/packer","slug":"only-one-of-script-or-scripts-can-be-specified","errorCode":null,"errorMessage":"Only one of script or scripts can be specified.","messagePattern":"Only one of script or scripts can be specified\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"provisioner/powershell/provisioner.go","lineNumber":226,"sourceCode":"\tif p.config.RemoteEnvVarPath == \"\" {\n\t\tuuid := uuid.TimeOrderedUUID()\n\t\tp.config.RemoteEnvVarPath = fmt.Sprintf(`c:/Windows/Temp/packer-ps-env-vars-%s.ps1`, uuid)\n\t}\n\n\tif p.config.Scripts == nil {\n\t\tp.config.Scripts = make([]string, 0)\n\t}\n\n\tif p.config.Vars == nil {\n\t\tp.config.Vars = make([]string, 0)\n\t}\n\n\tp.config.remoteCleanUpScriptPath = fmt.Sprintf(`c:/Windows/Temp/packer-cleanup-%s.ps1`, uuid.TimeOrderedUUID())\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.ElevatedUser == \"\" && p.config.ElevatedPassword != \"\" {\n\t\terrs = packersdk.MultiErrorAppend(errs,\n\t\t\terrors.New(\"Must supply an 'elevated_user' if 'elevated_password' provided\"))\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}","sourceCodeStart":208,"sourceCodeEnd":244,"githubUrl":"https://github.com/hashicorp/packer/blob/eb36e3c3e48a036f3e8cc94087636ee72e1303c9/provisioner/powershell/provisioner.go#L208-L244","documentation":"The PowerShell provisioner accepts a single script via the script field or a list via scripts, but never both. Prepare detects p.config.Script non-empty and len(p.config.Scripts) > 0 simultaneously and rejects the template because it cannot unambiguously determine which set of scripts to execute. This is ambiguous-configuration validation raised before any provisioning starts.","triggerScenarios":"A powershell provisioner block defining both script = \"./a.ps1\" and scripts = [\"./b.ps1\", \"./c.ps1\"]. Often happens after HCL2 variable interpolation injects a value into both fields.","commonSituations":"Merging snippet configs or modules where each sets a different field; converting a single-script block to scripts and forgetting to remove the old script key; conditional template logic accidentally populating both.","solutions":["Remove the script field and keep only scripts (move the single entry into the list).","Or remove scripts and keep only script if a single file is needed.","Check generated/HCL for-each logic that may set both fields from variables."],"exampleFix":"// before\nprovisioner \"powershell\" {\n  script  = \"./setup.ps1\"\n  scripts = [\"./install.ps1\", \"./config.ps1\"]\n}\n\n// after\nprovisioner \"powershell\" {\n  scripts = [\"./setup.ps1\", \"./install.ps1\", \"./config.ps1\"]\n}","handlingStrategy":"validation","validationCode":"// Before defining the block, pick one field:\n// single file  -> script = \"./x.ps1\"\n// multiple     -> scripts = [\"./a.ps1\"]\n// Never set both. Template assertion:\nassert {\n  condition     = !(var.use_single && var.use_multi)\n  error_message = \"Configure either script or scripts, not both.\"\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Standardize on scripts (list) for all powershell provisioners to avoid the dual-field ambiguity.","Run packer validate on the template after edits.","When combining config snippets, grep the merged block for both keys."],"tags":["packer","provisioner","powershell","config-validation"],"backgroundTag":"mutually-exclusive-fields","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"}