{"record":{"id":"1e18ca21f52962d2","repo":"windmill-labs/windmill","slug":"arg-binds-p-b-param-more-than-once","errorCode":null,"errorMessage":"--arg binds ${p}:${b.param} more than once.","messagePattern":"--arg binds (.+?):(.+?) more than once\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"cli/src/commands/pipeline/pipeline.ts","lineNumber":672,"sourceCode":"    const binding = parseUploadBinding(spec);\n    const id = resolveScriptTokenOrThrow(binding.scriptTok, \"--upload\");\n    const p = scriptPathOf(id);\n    (boundBindingsByPath.get(p) ?? boundBindingsByPath.set(p, []).get(p)!).push(binding);\n    boundNodeIds.add(id);\n  }\n\n  // `--arg <script>:<param>=<value>` overlays a plain run arg on a script in\n  // the selection. Unlike `--upload` it does not make the script a runnable\n  // start — it only supplies a value if the script runs.\n  const plainArgsByPath = new Map<string, Record<string, unknown>>();\n  for (const spec of opts.arg ?? []) {\n    const b = parseArgBinding(spec);\n    const p = scriptPathOf(resolveScriptTokenOrThrow(b.scriptTok, \"--arg\"));\n    const merged = plainArgsByPath.get(p) ?? plainArgsByPath.set(p, {}).get(p)!;\n    // Object.hasOwn, not `in`: a param named like a prototype member\n    // (`toString`, `constructor`, …) must not trip the duplicate check.\n    if (Object.hasOwn(merged, b.param)) {\n      throw new Error(`--arg binds ${p}:${b.param} more than once.`);\n    }\n    merged[b.param] = b.value;\n  }\n\n  // `// macros` libraries are definition-only: their macros are injected into\n  // consuming DuckDB scripts at run time, so \"running\" one is a no-op preview.\n  // They are excluded from starts and from every selection below (they'd\n  // otherwise read as manual roots, since nothing triggers them).\n  const macroLibPaths = new Set(\n    graph.runnables\n      .filter((r) => r.usage_kind === \"script\" && (r.macros?.length ?? 0) > 0)\n      .map((r) => r.path),\n  );\n  // Non-runnable graph nodes: the macro libraries above, plus (under `--local`)\n  // any script node with no local file. The local graph surfaces macro-consumer\n  // nodes for lineage display — a DuckDB script that calls a macro but isn't a\n  // `// pipeline` member (so has no previewable content). They must never enter\n  // the run: as a manual root they'd be scheduled, and a preview would fail with","sourceCodeStart":654,"sourceCodeEnd":690,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/pipeline/pipeline.ts#L654-L690","documentation":"Duplicate-binding guard for --arg in the pipeline run command: two or more --arg <script>:<param>=<value> bindings target the same script and param, so one would silently overwrite the other (later spreads win). The inputs at fault are the repeated --arg entries for that script:param pair.","triggerScenarios":"Thrown at cli/src/commands/pipeline/pipeline.ts:672 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Keep only one --arg per script:param pair","If two different params were intended, correct the param name in one binding","If you need a composite value, pass it as one JSON value: --arg script:param='{\\\"a\\\":1}'"],"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"}