windmill-labs/windmill · warning
--upload for ${p} is unused — it isn't in the run selection.
Error message
--upload for ${p} is unused — it isn't in the run selection. What it means
In `wmill pipeline run`, each --upload binding whose target script did not make it into the final run selection is a silent no-op, so the CLI warns per path. It tells you the binding value will never be consumed by this run.
Source
Thrown at cli/src/commands/pipeline/pipeline.ts:911
return defaultPartitionValue(kind);
};
if (opts.local && !opts.partition) {
const unresolvable = order.filter(
(p) => partitionKindByPath.get(p) === "dynamic",
);
if (unresolvable.length > 0) {
throw new Error(
`dynamic \`// partitioned\` script(s) need an explicit partition for a local run: ${unresolvable.sort().join(", ")} — pass --partition <value>.`,
);
}
}
// A `--upload` whose script fell outside the selection is a no-op the user
// should know about, rather than silently ignored.
const orderSet = new Set(order);
const boundInOrder = [...boundBindingsByPath.keys()].filter((p) => orderSet.has(p)).sort();
for (const p of boundBindingsByPath.keys()) {
if (!orderSet.has(p)) log.warn(`--upload for ${p} is unused — it isn't in the run selection.`);
}
for (const p of plainArgsByPath.keys()) {
if (!orderSet.has(p)) log.warn(`--arg for ${p} is unused — it isn't in the run selection.`);
}
if (opts.json) {
// Surface reachable/dropped ends so a machine-readable plan reflects the
// same trimming the human-facing warning does — a resolved-but-unreachable
// `--to` must not look like a clean plan that silently runs only the start.
console.log(
JSON.stringify({
start: runAll ? null : scriptPathOf(start!),
ends: ends.map(idLabel),
reachableEnds: reachableEnds.map(idLabel),
droppedEnds: droppedEnds.map(idLabel),
order,
cyclic,
uploads: boundInOrder,View on GitHub (pinned to e474e8803c)
Solutions
- Check the plan output (use --json to see reachable/dropped ends) and widen the selection (--start/--end) so the script runs.
- Correct the path in --upload if it is misspelled or renamed.
- Remove the unused --upload flag if the binding is no longer needed.
- Resolve cycles/barriers that excluded the script (see other warnings in the same run).
Example fix
// before: bound script not in selection wmill pipeline run f/myflow --start a --end b --upload f/myflow/c=file.csv // after: widen window to include c wmill pipeline run f/myflow --start a --end c --upload f/myflow/c=file.csv
Defensive patterns
Strategy: validation
Validate before calling
// confirm every --upload target is inside the planned selection
const plan = JSON.parse(execSync('wmill pipeline run f/x --start a --end b --json').toString());
const uploads = ['f/myflow/c'];
const missing = uploads.filter(p => !plan.order.includes(p));
if (missing.length) throw new Error(`--upload targets not in selection: ${missing}`); Prevention
- Re-derive --upload flags whenever you change --start/--end.
- Use --json plan output to verify the selection before the real run.
- Keep run commands in scripts that are updated together with the flow.
- Grep long run commands for stale flags before reusing them.
When it happens
Trigger: Passing --upload <path>=<value> for a script that was excluded from the selection — outside the --start/--end window, behind a barrier, on a cycle, filtered as not-runnable, or the path has a typo.
Common situations: Leftover --upload flags from a previous run invocation; uploading to a script that is not downstream of --start; a --to/--end narrowing that quietly excluded the bound script.
Related errors
- --arg for ${p} is unused — it isn't in the run selection.
- end '${idLabel(d)}' is not downstream of the start — ignored
- end '${idLabel(e)}' is only reachable through a skipped inpu
- Skipping ${cyclic.length} script(s) on a dependency cycle: $
- App ${appPath} not found
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/18d98397beccb56d.
Report an issue: GitHub.