windmill-labs/windmill · warning

Could not fetch ws_specific items from server (${status ?? "

Error message

Could not fetch ws_specific items from server (${status ?? "no status"}): ${msg}. Sync will proceed without server-side ws_specific items.

What it means

In `wmill sync`, the mergeWsSpecificFromServer step calls the server's listWsSpecific endpoint to fetch workspace-specific items. If the fetch throws an error that is not a 404 (404 is silently treated as 'endpoint not supported' and only debug-logged), this warning is emitted and sync continues using only local ws_specific items — server-side ws_specific items are dropped from the merge.

Source

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

}> {
  let wsSpecificItems: Array<{ item_kind: string; path: string }>;
  try {
    wsSpecificItems = await wmill.listWsSpecific({ workspace: workspaceId });
  } catch (err) {
    // 404 = endpoint not present on an older server: expected, log at debug.
    // Anything else (401/403/network) is a real failure that produces an
    // incomplete sync — surface it so the user notices.
    const isApiError =
      err &&
      typeof err === "object" &&
      "name" in err &&
      (err as { name: unknown }).name === "ApiError";
    const status = isApiError ? (err as { status?: number }).status : undefined;
    if (status === 404) {
      log.debug("listWsSpecific endpoint not available on server, skipping");
    } else {
      const msg = err instanceof Error ? err.message : String(err);
      log.warn(
        `Could not fetch ws_specific items from server (${status ?? "no status"}): ${msg}. ` +
          `Sync will proceed without server-side ws_specific items.`,
      );
    }
    return { merged: specificItems, serverItems: null };
  }

  if (wsSpecificItems.length === 0) {
    return { merged: specificItems, serverItems: wsSpecificItems };
  }

  const merged: SpecificItemsConfig = specificItems ? { ...specificItems } : {};

  for (const item of wsSpecificItems) {
    const configKey = configKeyForItemKind(item.item_kind);
    if (!configKey) continue;
    if (!merged[configKey]) {
      merged[configKey] = [];

View on GitHub (pinned to e474e8803c)

Solutions

  1. Check the logged status code: if 401/403, refresh credentials or grant the user workspace access (`wmill workspace add` with a fresh token).
  2. If 5xx or network error, verify the server is healthy (curl the backend URL) and retry the sync.
  3. Upgrade the Windmill server so the ws_specific endpoint exists and returns a proper 404 when unsupported.
  4. If server-side ws_specific items are not needed, ignore the warning — sync proceeds with local items only.

Example fix

// before (endpoint missing/old server)
wmill sync push  # warns: Could not fetch ws_specific items from server (501): ...
// after: upgrade server, or check auth
wmill workspace switch <workspace> && wmill sync push
Defensive patterns

Strategy: fallback

Validate before calling

// preflight: check the endpoint and auth before syncing
const res = await fetch(`${baseUrl}/api/w/<workspace>/ws_specific/list`, {
  headers: { Authorization: `Bearer ${token}` },
});
if (!res.ok && res.status !== 404) {
  console.error(`ws_specific endpoint not usable: HTTP ${res.status}; fix auth/server before sync`);
}

Type guard

function isApiError(e: unknown): e is { name: 'ApiError'; status?: number } {
  return typeof e === 'object' && e !== null && (e as { name?: unknown }).name === 'ApiError';
}

Try / catch

try {
  await mergeWsSpecificFromServer();
} catch (err) {
  if (isApiError(err) && err.status === 404) {
    log.debug('endpoint unsupported, skipping');
  } else {
    log.warn(`sync proceeds without server ws_specific items: ${err}`);
  }
}

Prevention

When it happens

Trigger: Calling `wmill sync` against a server whose ws_specific list endpoint returns a non-404 error: server version too old for the endpoint, network failure, auth/permission rejection (401/403), or a 500 from the backend.

Common situations: Syncing a new CLI against an older Windmill server that predates ws_specific support but returns something other than 404; expired/insufficient workspace token; transient network outage or proxy error during sync.

Understand the failure class

Background: 'Something went wrong' / 'Request failed (500)' / 'HTTP error! status: 404' — what failed HTTP requests actually mean and how to find the real cause — this error's family across 28 libraries.

Related errors


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