{"record":{"id":"f230c5c23b6b5518","repo":"windmill-labs/windmill","slug":"scriptpath-has-multiple-s3object-parameters","errorCode":null,"errorMessage":"${scriptPath} has multiple S3Object parameters (${params.join(\", \")}) — pick one with --upload ${binding.scriptTok}:<param>=${binding.source}","messagePattern":"(.+?) has multiple S3Object parameters \\((.+?)\\) — pick one with --upload (.+?):<param>=(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/pipeline/pipeline.ts","lineNumber":498,"sourceCode":"        throw new Error(`No local file for ${scriptPath} to infer its S3Object parameter.`);\n      }\n      schema = (await inferSchema(ls.language as any, ls.content, {}, scriptPath)).schema;\n    } else {\n      schema = (await wmill.getScriptByPath({ workspace: workspaceId, path: scriptPath })).schema;\n    }\n    return schema;\n  };\n\n  const args: Record<string, any> = {};\n  for (const binding of bindings) {\n    let param = binding.param;\n    if (!param) {\n      const params = s3ObjectParams(await loadSchema());\n      if (params.length === 1) param = params[0];\n      else if (params.length === 0) {\n        throw new Error(`${scriptPath} declares no S3Object parameter to bind --upload to.`);\n      } else {\n        throw new Error(\n          `${scriptPath} has multiple S3Object parameters (${params.join(\", \")}) — pick one with --upload ${binding.scriptTok}:<param>=${binding.source}`,\n        );\n      }\n    }\n    if (param in args) {\n      throw new Error(`--upload binds ${scriptPath}:${param} more than once.`);\n    }\n    let obj: { s3: string; storage?: string };\n    if (binding.source.startsWith(\"s3://\")) {\n      // Canonical `s3://<storage>/<key>`; keeps named storage (see parseS3Uri).\n      obj = parseS3Uri(binding.source);\n    } else {\n      const buf = await readFile(binding.source);\n      // Key scoped by script + param so distinct sources sharing a basename\n      // (across scripts or params) don't clobber each other in the store.\n      const key = devUploadKey(scriptPath, param, binding.source);\n      await wmill.fileUpload({\n        workspace: workspaceId,","sourceCodeStart":480,"sourceCodeEnd":516,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/pipeline/pipeline.ts#L480-L516","documentation":"Disambiguation error while resolving a --upload binding in the pipeline run command: the target script's schema has more than one S3Object-typed parameter, no explicit param name was given in the binding, and the CLI refuses to guess which one receives the uploaded file. The message lists the candidate parameter names and shows the exact syntax to disambiguate. The inputs at fault are the --upload spec (missing :<param>) and the script's schema declaring multiple S3Object params.","triggerScenarios":"Thrown at cli/src/commands/pipeline/pipeline.ts:498 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Re-run with the param named explicitly: --upload <script>:<param>=<file-or-s3-uri> using one of the listed candidates","If only one param should be S3Object, change the script's schema so the other parameter is a plain string/type"],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}