{"record":{"id":"f3d43655404f13a9","repo":"windmill-labs/windmill","slug":"could-not-fetch-ws-specific-items-from-server-s","errorCode":null,"errorMessage":"Could not fetch ws_specific items from server (${status ?? \"no status\"}): ${msg}. Sync will proceed without server-side ws_specific items.","messagePattern":"Could not fetch ws_specific items from server \\((.+?)\\): (.+?)\\. Sync will proceed without server-side ws_specific items\\.","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"cli/src/commands/sync/sync.ts","lineNumber":364,"sourceCode":"}> {\n  let wsSpecificItems: Array<{ item_kind: string; path: string }>;\n  try {\n    wsSpecificItems = await wmill.listWsSpecific({ workspace: workspaceId });\n  } catch (err) {\n    // 404 = endpoint not present on an older server: expected, log at debug.\n    // Anything else (401/403/network) is a real failure that produces an\n    // incomplete sync — surface it so the user notices.\n    const isApiError =\n      err &&\n      typeof err === \"object\" &&\n      \"name\" in err &&\n      (err as { name: unknown }).name === \"ApiError\";\n    const status = isApiError ? (err as { status?: number }).status : undefined;\n    if (status === 404) {\n      log.debug(\"listWsSpecific endpoint not available on server, skipping\");\n    } else {\n      const msg = err instanceof Error ? err.message : String(err);\n      log.warn(\n        `Could not fetch ws_specific items from server (${status ?? \"no status\"}): ${msg}. ` +\n          `Sync will proceed without server-side ws_specific items.`,\n      );\n    }\n    return { merged: specificItems, serverItems: null };\n  }\n\n  if (wsSpecificItems.length === 0) {\n    return { merged: specificItems, serverItems: wsSpecificItems };\n  }\n\n  const merged: SpecificItemsConfig = specificItems ? { ...specificItems } : {};\n\n  for (const item of wsSpecificItems) {\n    const configKey = configKeyForItemKind(item.item_kind);\n    if (!configKey) continue;\n    if (!merged[configKey]) {\n      merged[configKey] = [];","sourceCodeStart":346,"sourceCodeEnd":382,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/cli/src/commands/sync/sync.ts#L346-L382","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Check the logged status code: if 401/403, refresh credentials or grant the user workspace access (`wmill workspace add` with a fresh token).","If 5xx or network error, verify the server is healthy (curl the backend URL) and retry the sync.","Upgrade the Windmill server so the ws_specific endpoint exists and returns a proper 404 when unsupported.","If server-side ws_specific items are not needed, ignore the warning — sync proceeds with local items only."],"exampleFix":"// before (endpoint missing/old server)\nwmill sync push  # warns: Could not fetch ws_specific items from server (501): ...\n// after: upgrade server, or check auth\nwmill workspace switch <workspace> && wmill sync push","handlingStrategy":"fallback","validationCode":"// preflight: check the endpoint and auth before syncing\nconst res = await fetch(`${baseUrl}/api/w/<workspace>/ws_specific/list`, {\n  headers: { Authorization: `Bearer ${token}` },\n});\nif (!res.ok && res.status !== 404) {\n  console.error(`ws_specific endpoint not usable: HTTP ${res.status}; fix auth/server before sync`);\n}","typeGuard":"function isApiError(e: unknown): e is { name: 'ApiError'; status?: number } {\n  return typeof e === 'object' && e !== null && (e as { name?: unknown }).name === 'ApiError';\n}","tryCatchPattern":"try {\n  await mergeWsSpecificFromServer();\n} catch (err) {\n  if (isApiError(err) && err.status === 404) {\n    log.debug('endpoint unsupported, skipping');\n  } else {\n    log.warn(`sync proceeds without server ws_specific items: ${err}`);\n  }\n}","preventionTips":["Keep the Windmill server version in sync with the CLI version.","Validate workspace tokens before CI sync runs.","Treat this warning as informational if you intentionally do not use ws_specific items.","Monitor the logged status code to distinguish auth (401/403) from server bugs (5xx)."],"tags":["cli","sync","network","http"],"backgroundTag":"http-request-failed","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"}