{"record":{"id":"85cd2c1ad3e92c3d","repo":"windmill-labs/windmill","slug":"end-idlabel-d-is-not-downstream-of-the-start","errorCode":null,"errorMessage":"end '${idLabel(d)}' is not downstream of the start — ignored.","messagePattern":"end '(.+?)' is not downstream of the start — ignored\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/src/commands/pipeline/pipeline.ts","lineNumber":843,"sourceCode":"    ),\n  );\n  let selectedScripts: Set<string>;\n  let reachableEnds: string[] = [];\n  let droppedEnds: string[] = [];\n  if (runAll) {\n    // Whole pipeline = everything reachable from the valid starts (schedule/manual\n    // roots), cutting at the barriers above. A node reachable via another,\n    // non-barrier path still runs.\n    selectedScripts = new Set(scriptsOf(reachableCutting(dag, starts, barriers)));\n  } else if (ends.length === 0) {\n    // No bound → full read-aware downstream of start (pure readers included),\n    // still cut at barriers so an event/upload descendant isn't run empty.\n    selectedScripts = new Set(scriptsOf(reachableCutting(dag, [start!], barriers)));\n  } else {\n    const res = boundedSet(dag, start!, ends);\n    droppedEnds = res.droppedEnds;\n    for (const d of droppedEnds) {\n      log.warn(`end '${idLabel(d)}' is not downstream of the start — ignored.`);\n    }\n    // Intersect the bounded window with the barrier-cut closure from the start so\n    // a barrier (or a node only reachable through one) inside the window is dropped.\n    const reachable = reachableCutting(dag, [start!], barriers);\n    selectedScripts = new Set(\n      scriptsOf([...res.nodes].filter((n) => reachable.has(n))),\n    );\n    // An end that boundedSet reached but the barrier cut removed is NOT satisfied:\n    // report it as dropped (not reachable) and warn, so `--json`/the plan don't\n    // claim a bound was met when its only path ran through a skipped handler.\n    for (const e of res.reachableEnds) {\n      if (reachable.has(e)) {\n        reachableEnds.push(e);\n      } else {\n        droppedEnds.push(e);\n        log.warn(\n          `end '${idLabel(e)}' is only reachable through a skipped input/event handler — not run (bind it with --upload to include it).`,\n        );","sourceCodeStart":825,"sourceCodeEnd":861,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/pipeline/pipeline.ts#L825-L861","documentation":"In `wmill pipeline run`, when an --end target is not downstream of the resolved --start node, boundedSet drops it and this warning names each dropped end. The run still proceeds with the reachable window; the unreachable --end is simply ignored.","triggerScenarios":"Running a sub-window of a pipeline with --start X --end Y where Y is not reachable from X in the pipeline DAG (typo in the end path/name, or ends that sit on a parallel branch).","commonSituations":"Misspelled or stale script path passed to --end after refactoring the flow; assuming --end accepts multiple arbitrary nodes rather than descendants of --start; copy-pasting ends from a different pipeline.","solutions":["Fix the --end value to a path/id that is downstream of --start (check the pipeline graph in the UI).","Remove the invalid --end and rerun without it.","Verify the script path exists and wasn't renamed (wmill pipeline script list or the UI).","If you meant a different starting point, adjust --start so the end is actually reachable."],"exampleFix":"// before\nwmill pipeline run f/myflow --start preprocess --end trainning  # typo, not downstream\n// after\nwmill pipeline run f/myflow --start preprocess --end training","handlingStrategy":"validation","validationCode":"// verify ends are downstream of start using the plan output before running\nconst plan = JSON.parse(execSync(`wmill pipeline run f/x --start ${start} --end ${end} --json --dry-run 2>/dev/null`).toString());\nif (plan.droppedEnds?.length) throw new Error(`invalid --end: ${plan.droppedEnds.join(',')}`);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Validate --start/--end against the pipeline graph in the UI before running.","Use exact script paths/ids, not display names.","Update run scripts after renaming flow steps.","Use --json output to confirm droppedEnds is empty."],"tags":["cli","pipeline","dag","invalid-argument"],"backgroundTag":"node-not-downstream","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"}