{"record":{"id":"307e82b35d0b20ca","repo":"windmill-labs/windmill","slug":"syncpushdestructivewarning-opts-keepdeleted","errorCode":null,"errorMessage":"⚠ ${syncPushDestructiveWarning(opts.keepDeleted)}","messagePattern":"⚠ \\$\\{syncPushDestructiveWarning\\(opts\\.keepDeleted\\)\\}","errorType":"console","errorClass":null,"httpStatus":null,"severity":"info","filePath":"cli/src/commands/sync/sync.ts","lineNumber":5541,"sourceCode":"            folderDefaultAnnotations.set(change.path, rule.permissioned_as);\n            break;\n          }\n        }\n      }\n    }\n\n    if (!opts.jsonOutput) {\n      prettyChanges(\n        changes,\n        specificItems,\n        wsNameForFiles,\n        folderDefaultAnnotations,\n      );\n    }\n\n    if (opts.dryRun) {\n      log.info(colors.gray(`Dry run complete.`));\n      log.warn(\n        colors.yellow(`\\n⚠ ${syncPushDestructiveWarning(opts.keepDeleted)}`),\n      );\n      return;\n    }\n\n    let permissionedAsContext: PermissionedAsContext | undefined = undefined;\n    if (parseSyncBehavior(opts.syncBehavior) >= 1) {\n      const user = await wmill.whoami({ workspace: workspace.workspaceId });\n      const userIsAdminOrDeployer =\n        user.is_admin || (user.groups ?? []).includes(\"wm_deployers\");\n      log.debug(\n        `permissioned_as: user=${user.email}, is_admin=${user.is_admin}, groups=${JSON.stringify(user.groups)}, isAdminOrDeployer=${userIsAdminOrDeployer}`,\n      );\n      permissionedAsContext = {\n        userCache: new Map(),\n        userIsAdminOrDeployer,\n        userEmail: user.email,\n      };","sourceCodeStart":5523,"sourceCodeEnd":5559,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/sync/sync.ts#L5523-L5559","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","solutions":["No action required — this is the expected dry-run summary.","Review the listed changes above the warning to confirm deletions are intended.","Re-run a real push with --keep-delete (or ensure keepDeleted is set) if you want remote items preserved even when missing locally."],"exampleFix":"// To avoid deletions on the real push:\n// before\nwmill sync push --dry-run\n// after\nwmill sync push --keep-delete --dry-run  # then real push with the same flag","handlingStrategy":"validation","validationCode":"// Dry-run first and diff deletions against an allowlist before real push:\nconst out = await runSyncPush({ ...opts, dryRun: true, jsonOutput: true });\nconst deletes = out.changes.filter((c) => c.changeType === 'DELETE');\nif (deletes.length > 0 && !process.env.ALLOW_DELETES) throw new Error('Deletions pending; refusing');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always dry-run before pushing to shared/production workspaces","Use --keep-delete (keepDeleted) when local deletions should not propagate","Gate pushes behind CI review of the dry-run change list","Document destructive sync semantics for your team"],"tags":["cli","sync","dry-run","destructive-changes"],"backgroundTag":"sync-push-destructive-warning","analyzedSha":"e474e8803ce2ff5c2df09a58dab51d45f5c922ca","analyzedAt":"2026-09-03T12:38:19.024Z","contentChangedAt":"2026-09-03T12:38:19.024Z","schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}