windmill-labs/windmill · info

⚠ ${syncPushDestructiveWarning(opts.keepDeleted)}

Error message

⚠ ${syncPushDestructiveWarning(opts.keepDeleted)}

What it means

At the end of a successful `wmill sync push --dry-run`, the CLI prints a warning reminding the user that a real push would apply destructive changes (deletions of remote resources missing locally, unless keepDeleted is set). This is informational, not a failure — the sync command completed its dry run.

Source

Thrown at cli/src/commands/sync/sync.ts:5541

            folderDefaultAnnotations.set(change.path, rule.permissioned_as);
            break;
          }
        }
      }
    }

    if (!opts.jsonOutput) {
      prettyChanges(
        changes,
        specificItems,
        wsNameForFiles,
        folderDefaultAnnotations,
      );
    }

    if (opts.dryRun) {
      log.info(colors.gray(`Dry run complete.`));
      log.warn(
        colors.yellow(`\n⚠ ${syncPushDestructiveWarning(opts.keepDeleted)}`),
      );
      return;
    }

    let permissionedAsContext: PermissionedAsContext | undefined = undefined;
    if (parseSyncBehavior(opts.syncBehavior) >= 1) {
      const user = await wmill.whoami({ workspace: workspace.workspaceId });
      const userIsAdminOrDeployer =
        user.is_admin || (user.groups ?? []).includes("wm_deployers");
      log.debug(
        `permissioned_as: user=${user.email}, is_admin=${user.is_admin}, groups=${JSON.stringify(user.groups)}, isAdminOrDeployer=${userIsAdminOrDeployer}`,
      );
      permissionedAsContext = {
        userCache: new Map(),
        userIsAdminOrDeployer,
        userEmail: user.email,
      };

View on GitHub (pinned to e474e8803c)

Solutions

  1. No action required — this is the expected dry-run summary.
  2. Review the listed changes above the warning to confirm deletions are intended.
  3. Re-run a real push with --keep-delete (or ensure keepDeleted is set) if you want remote items preserved even when missing locally.

Example fix

// To avoid deletions on the real push:
// before
wmill sync push --dry-run
// after
wmill sync push --keep-delete --dry-run  # then real push with the same flag
Defensive patterns

Strategy: validation

Validate before calling

// Dry-run first and diff deletions against an allowlist before real push:
const out = await runSyncPush({ ...opts, dryRun: true, jsonOutput: true });
const deletes = out.changes.filter((c) => c.changeType === 'DELETE');
if (deletes.length > 0 && !process.env.ALLOW_DELETES) throw new Error('Deletions pending; refusing');

Prevention

When it happens

Trigger: Every `wmill sync push --dry-run` that completes successfully emits this warning, showing what the destructive behavior would be on a real push (governed by --keep-delete / opts.keepDeleted).

Common situations: Previewing a sync where local files were removed and a real push would delete the corresponding remote items; routine dry-run before CI/CD deployment.

Related errors


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