windmill-labs/windmill · error

Cannot push flow ${remotePath}: step(s) reference non-worksp

Error message

Cannot push flow ${remotePath}: step(s) reference non-workspace path(s): ${badStepPaths.join(", ")}. Flow step paths must be workspace paths (u/, f/, g/ or hub/), not absolute or local filesystem paths. This usually means flow.yaml was generated with paths from a checkout directory.

What it means

`wmill flow push` validates that every step path in the flow is a workspace path (u/, f/, g/ or hub/ prefixed). If `collectStepPaths` finds absolute or local filesystem paths (e.g. /tmp/.../ops/scripts/...), it throws this fail-fast error, because such steps would silently mis-resolve at runtime; the backend re-validates the same rule (#9751).

Source

Thrown at cli/src/commands/flow/flow.ts:231

    // Hard-fail rather than push the literal `!inline path` text as
    // rawscript.content. That string would be persisted in flow_version.value
    // and round-trip as the script body on the next pull, overwriting the
    // user's local handler with the directive — see GIT-871 / #9140.
    throw new Error(
      `Cannot push flow ${remotePath}: missing inline script file(s): ${missingFiles.join(", ")}. ` +
      `Either restore the file(s) or remove the !inline reference(s) from flow.yaml before pushing.`
    );
  }

  // Reject script/sub-flow steps whose path is not a workspace path (u/, f/, g/ or hub/).
  // A flow.yaml generated from a feature-branch checkout can carry absolute local paths
  // (e.g. /tmp/.../ops/scripts/...); pushed, they silently mis-resolve at runtime (#9751).
  // The backend re-validates the same rule for every step type, so this is a fail-fast.
  const badStepPaths = collectStepPaths(localFlow.value).filter(
    (p) => p !== "" && !/^(u|f|g|hub)\//.test(p)
  );
  if (badStepPaths.length > 0) {
    throw new Error(
      `Cannot push flow ${remotePath}: step(s) reference non-workspace path(s): ${badStepPaths.join(", ")}. ` +
      `Flow step paths must be workspace paths (u/, f/, g/ or hub/), not absolute or local filesystem paths. ` +
      `This usually means flow.yaml was generated with paths from a checkout directory.`
    );
  }

  const hasOnBehalfOf = (localFlow as any).has_on_behalf_of ?? !!localFlow.on_behalf_of_email;
  delete (localFlow as any).has_on_behalf_of;
  // The authorization half of the identity is never exported to the repo (the
  // workspace tarball strips it); it only ever travels back from the remote row.
  delete (localFlow as any).on_behalf_of;

  const preserveFields: {
    on_behalf_of_email?: string;
    on_behalf_of?: string;
    preserve_on_behalf_of?: boolean;
  } = {};
  if (permissionedAsContext?.userIsAdminOrDeployer && hasOnBehalfOf) {

View on GitHub (pinned to e474e8803c)

Solutions

  1. Edit flow.yaml and replace each listed path with a workspace path (u/user/..., f/folder/..., g/..., or hub/...).
  2. Re-generate the flow with tooling configured to emit workspace-relative paths.
  3. Pre-create referenced scripts in the workspace and reference them by their workspace path.

Example fix

// before (flow.yaml)
path: /tmp/checkout/ops/scripts/notify.ts
// after
path: u/admin/notify
Defensive patterns

Strategy: validation

Validate before calling

const WS_PATH = /^(u|f|g|hub)\//;
const bad = stepPaths(flow).filter(p => p !== '' && !WS_PATH.test(p));
if (bad.length) throw new Error('non-workspace step paths: ' + bad.join(', '));

Type guard

function isWorkspacePath(p: string): boolean { return /^(u|f|g|hub)\//.test(p); }

Try / catch

try { await pushFlow(...) } catch (e) { if (String(e).includes('non-workspace path')) rewriteStepPathsToWorkspace(flowYaml); else throw e; }

Prevention

When it happens

Trigger: Pushing a flow.yaml generated with local checkout paths embedded in step path fields — typically from AI generation or tooling that wrote absolute paths from the machine's checkout directory instead of workspace paths.

Common situations: Flows scaffolded by scripts/agents that pasted filesystem paths; copying flow.yaml between machines; editing flow.yaml by hand with absolute paths; flows exported from another system.

Related errors


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