windmill-labs/windmill · warning

Could not read the shared UI folder from the remote; skippin

Error message

Could not read the shared UI folder from the remote; skipping its push so --keep-deleted does not clear it.

What it means

Pushing the shared UI folder writes the remote store wholesale: remote-only files are pruned by omission of the local set. If the remote store cannot be read at all while --keep-deleted is set, pruning by omission would delete everything, so the push of the shared UI is skipped entirely and a warning is emitted instead of clearing the remote.

Source

Thrown at cli/src/commands/shared_ui.ts:129

 * pushes an empty map (clearing the remote store) if the remote is non-empty —
 * unless `keepDeleted`, which folds remote-only files back into the map.
 */
export async function pushSharedUi(
  workspace: string,
  keepDeleted?: boolean,
): Promise<boolean> {
  const localDir = path.join(process.cwd(), SHARED_UI_DIR);
  if (!fs.existsSync(localDir)) {
    return false;
  }

  const files = await readDirRecursive(localDir);
  const remote = await fetchSharedUi(workspace);
  // The store is written whole, so a remote-only file is pruned by omission
  // alone. An unreadable store leaves no way to carry those files over, so
  // the shared UI is left untouched rather than cleared.
  if (remote === undefined && keepDeleted) {
    log.warn(
      colors.yellow(
        "Could not read the shared UI folder from the remote; skipping its push so --keep-deleted does not clear it.",
      ),
    );
    return false;
  }

  // Same comparison as diffSharedUi, off the same two maps, so preview and
  // push never diverge.
  if (sharedUiChanges(files, remote ?? {}, keepDeleted).length === 0) {
    log.info(colors.gray("Shared UI folder up to date"));
    return false;
  }

  if (keepDeleted) {
    for (const [rel, content] of Object.entries(remote!)) {
      // defineProperty, not assignment: `files.__proto__ = "..."` runs the
      // inherited setter and creates no own property, so a remote `ui/__proto__`

View on GitHub (pinned to e474e8803c)

Solutions

  1. Investigate why fetchSharedUi failed (check backend version, auth, workspace) and fix it, then re-push
  2. Drop --keep-deleted for this run if you actually intend to replace the remote shared UI
  3. Verify the remote shared UI contents after fixing, since the push was skipped

Example fix

// before
wmill sync push --keep-deleted   # shared UI skipped: remote unreadable
// after
wmill sync push   # without --keep-deleted, or fix backend/auth first then re-run with --keep-deleted
Defensive patterns

Strategy: validation

Validate before calling

if (await fetchSharedUi(workspace) === undefined) console.warn('avoid --keep-deleted');

Type guard

function sharedUiReadable(v: unknown): v is Record<string, string> { return typeof v === 'object' && v !== null; }

Try / catch

try { await pushSharedUi({workspace, keepDeleted:true}); } catch { console.warn('shared UI push skipped; nothing deleted'); }

Prevention

When it happens

Trigger: Running a push with --keep-deleted when fetchSharedUi() returns undefined — the remote shared UI store is unreadable/missing due to API error, old backend, or permission problems.

Common situations: Older backends without the shared UI store endpoint; transient API/auth failures during sync; workspaces where shared UI was never initialized remotely.

Related errors


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