windmill-labs/windmill · error

Failed to create flow ${remotePath}: ${e.body ?? e.message}

Error message

Failed to create flow ${remotePath}: ${e.body ?? e.message}

What it means

This error wraps any failure from the Windmill API when the CLI attempts to create a flow via `wmill flow push`. The thrown message interpolates the target remote path and the API error body (or message if the SDK didn't parse a body), so it is a generic wrapper around upstream create-flow failures such as validation errors, conflicts, or auth problems.

Source

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

        },
      });
    }
  } else {
    log.info(colors.bold.yellow("Creating new flow..."));
    try {
      await wmill.createFlow({
        workspace: workspace,
        requestBody: {
          path: remotePath.replaceAll(SEP, "/"),
          deployment_message: message,
          ...localFlowBody,
          ...preserveFields,
          // Preserve any user draft at this path (see backend skip_draft_deletion).
          skip_draft_deletion: true,
        },
      });
    } catch (e) {
      throw new Error(
        //@ts-ignore
        `Failed to create flow ${remotePath}: ${e.body ?? e.message}`
      );
    }
  }

  // Independent of whether the flow body changed, sync extra_perms via /acls/*.
  // Self-contained log line + non-fatal failures.
  //
  // No refetch is needed: extra_perms is item-specific and additive on top of
  // folder perms — folder perms are never merged onto item.extra_perms. And
  // since the request body sent to update_flow / create_flow doesn't carry
  // extra_perms, the value we read in the initial getFlowByPath above is
  // also the post-write value (a no-op deploy can't drift it).
  await applyExtraPermsDiff(
    workspace,
    "flow",
    remotePath.replaceAll(SEP, "/"),

View on GitHub (pinned to e474e8803c)

Solutions

  1. Inspect the interpolated error body — it contains the server's validation message; fix the flow definition accordingly
  2. Verify the token/workspace has write permissions for flows (`wmill workspace` shows the active one)
  3. Validate the flow.yaml locally with `wmill flow validate` if available, or push once with the frontend UI to surface the field error
  4. Check CLI/server version compatibility and upgrade the CLI

Example fix

// before
wmill flow push f/policies/audit --skip-partial-validation
// after
wmill flow validate f/policies/audit && wmill flow push f/policies/audit
Defensive patterns

Strategy: try-catch

Validate before calling

const exists = await wmill.getFlowByPath({ workspace, path: remotePath }).catch(() => null);
if (exists) console.warn(`Flow ${remotePath} already exists; it will be updated`);
if (!flowValue?.value?.modules?.length) throw new Error('flow value has no modules');

Type guard

function isApiError(e: unknown): e is { body?: { message?: string }; message: string } {
  return typeof e === 'object' && e !== null && 'message' in e;
}

Try / catch

try {
  await wmill.createFlow({ workspace, path: remotePath, requestBody: flowValue });
} catch (e) {
  const detail = (e as any)?.body?.message ?? (e as any)?.message ?? String(e);
  console.error(`Push of ${remotePath} rejected by server: ${detail}`);
  process.exitCode = 1;
}

Prevention

When it happens

Trigger: Running `wmill flow push` (or pushObj) where the POST/UPDATE to create the flow fails: invalid flow value YAML/JSON, a path conflict with different resource kind, missing workspace permission, or malformed `skip_draft_deletion`/preserveFields payload.

Common situations: Deploying flows from CI where the token lacks write access; pushing a flow.yaml edited by hand with invalid module structure; pushing to a workspace where the path is taken by a script/app; API version drift between CLI and server.

Related errors


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