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
- Choose a different path for the new trigger
- Delete or rename the existing YAML file if it is obsolete, then re-run
- Edit the existing file instead of creating a new trigger
- 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
- Make init scripts idempotent (check existence before new)
- Use unique base paths per trigger
- Keep trigger YAML files in git to see what already exists
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
- Datatable '${dtName}' already exists in this workspace
- File already exists: + scriptCodeFileFullPath
- File already exists: + scriptMetadataFileFullPath
- --kind is required. Valid kinds: ${TRIGGER_TYPES.join(", ")}
- Invalid trigger kind: ${opts.kind}. Valid kinds: ${TRIGGER_T
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/849dcdcfadd78589.
Report an issue: GitHub.