windmill-labs/windmill · error · Error

--from '${opts.from}' matches multiple scripts (${matches.ma

Error message

--from '${opts.from}' matches multiple scripts (${matches.map((r) => r.path).sort().join(", ")}) — pass the full path.

What it means

Ambiguity guard when resolving --from in the pipeline run command: the token's basename matches multiple script nodes in the graph (resolveToken returned nothing because it can't disambiguate, and the fallback basename scan found >1). The message lists the matching full paths sorted; the input at fault is the abbreviated --from token.

Source

Thrown at cli/src/commands/pipeline/pipeline.ts:736

      (id) => !notRunnablePaths.has(scriptPathOf(id)),
    ),
  );
  // `runAll` = no `--from` on a multi-root pipeline (fan-in): run the whole
  // pipeline in topological order rather than forcing a single start, the way
  // `dbt run` (no `--select`) runs the entire project. `--to` still needs an
  // explicit `--from` since bounding is relative to one start.
  let runAll = false;
  let start: string | undefined;
  if (opts.from) {
    const resolved = resolveToken(graph, opts.from);
    if (!resolved) {
      // Distinguish "no match" from "ambiguous short name" (resolveToken
      // returns undefined for both) so the hint is actionable.
      const matches = graph.runnables.filter(
        (r) => r.usage_kind === "script" && (r.path.split("/").pop() ?? r.path) === opts.from,
      );
      if (matches.length > 1) {
        throw new Error(
          `--from '${opts.from}' matches multiple scripts (${matches.map((r) => r.path).sort().join(", ")}) — pass the full path.`,
        );
      }
      throw new Error(`--from '${opts.from}' matched no script in f/${f}.`);
    }
    if (macroLibPaths.has(scriptPathOf(resolved))) {
      throw new Error(
        `--from '${opts.from}' is a \`// macros\` library — definition-only, injected into consuming scripts at run time, never a runnable step.`,
      );
    }
    // A `--local` display-only node (a non-`// pipeline` DuckDB script surfaced
    // only because it calls a macro) has no previewable content — reject it
    // clearly rather than admitting it and silently producing an empty plan.
    if (notRunnablePaths.has(scriptPathOf(resolved))) {
      throw new Error(
        `--from '${opts.from}' isn't a \`// pipeline\` script — it appears in the local graph only as a macro consumer (lineage). Mark it \`// pipeline\` to run it.`,
      );
    }

View on GitHub (pinned to e474e8803c)

Solutions

  1. Pass the full script path in --from using one of the listed candidates
  2. Rename one of the colliding scripts so the short name is unique
Defensive patterns

Strategy: validation

When it happens

Trigger: Thrown at cli/src/commands/pipeline/pipeline.ts:736 when the library encounters an invalid state.

Common situations: See trigger scenarios.


AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03). Data as JSON: /api/errors/54890a1c41a45f45. Report an issue: GitHub.