windmill-labs/windmill · error · Error

File already exists: ${filePath}

Error message

File already exists: ${filePath}

What it means

`wmill trigger new` writes a YAML template for the new trigger and refuses to overwrite an existing file: it stats the target path `{path}.{kind}_trigger.yaml` and throws this error if it exists. The catch block explicitly re-throws errors starting with "File already exists" so stat failures (ENOENT) fall through and creation proceeds.

Source

Thrown at cli/src/commands/trigger/trigger.ts:445

    enabled: false,
  },
};

async function newTrigger(opts: GlobalOptions & { kind: string }, path: string) {
  if (!validatePath(path)) {
    return;
  }
  if (!opts.kind) {
    throw new Error("--kind is required. Valid kinds: " + TRIGGER_TYPES.join(", "));
  }
  if (!checkIfValidTrigger(opts.kind)) {
    throw new Error("Invalid trigger kind: " + opts.kind + ". Valid kinds: " + TRIGGER_TYPES.join(", "));
  }
  const kind: TriggerType = opts.kind;
  const filePath = `${path}.${kind}_trigger.yaml`;
  try {
    await stat(filePath);
    throw new Error("File already exists: " + filePath);
  } catch (e: any) {
    if (e.message?.startsWith("File already exists")) throw e;
  }
  const template = triggerTemplates[kind];
  await mkdir(dirname(filePath), { recursive: true });
  await writeFile(filePath, yamlStringify(template), {
    flag: "wx",
    encoding: "utf-8",
  });
  log.info(colors.green(`Created ${filePath}`));
}

const TRIGGER_SKIP_FIELDS = new Set(["workspace_id", "extra_perms", "edited_by", "edited_at"]);

function printTriggerDetails(trigger: any, kind: string) {
  console.log(colors.bold("Path:") + " " + trigger.path);
  console.log(colors.bold("Kind:") + " " + kind);
  console.log(colors.bold("Enabled:") + " " + (trigger.enabled ?? trigger.mode ?? "-"));

View on GitHub (pinned to e474e8803c)

Solutions

  1. Choose a different path for the new trigger
  2. Delete or rename the existing YAML file if it is obsolete, then re-run
  3. Edit the existing file instead of creating a new trigger
  4. Use the existing trigger remotely via `wmill trigger get` to verify it before recreating

Example fix

// before
wmill trigger new u/admin/myscript --kind schedule
# Error: File already exists: u/admin/myscript.schedule_trigger.yaml
// after
wmill trigger new u/admin/myscript_v2 --kind schedule
Defensive patterns

Strategy: try-catch

Validate before calling

import { stat } from "fs/promises";
const target = `${path}.${kind}_trigger.yaml`;
const exists = await stat(target).then(() => true, () => false);
if (exists) console.warn("trigger file already present, pick another path or edit it");

Try / catch

try {
  await wmill.trigger.new(opts, p);
} catch (e) {
  if (String(e.message).startsWith("File already exists")) {
    console.warn(e.message, "— edit existing file or choose a new path");
  }
}

Prevention

When it happens

Trigger: Running `wmill trigger new u/admin/myscript --kind schedule` twice, or when a file u/admin/myscript.schedule_trigger.yaml already exists from a previous creation or sync pull.

Common situations: Re-running an init script that isn't idempotent; onboarding docs executed twice; collisions when several triggers share the same base path and kind naming.

Understand the failure class

Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.

Related errors


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