{"record":{"id":"950b2ee696e882d3","repo":"windmill-labs/windmill","slug":"apierror-with-mapped-http-status-message-e-g-no","errorCode":null,"errorMessage":"ApiError with mapped HTTP status message (e.g. \"Not Found\", \"Internal Server Error\") for non-2xx responses","messagePattern":"ApiError with mapped HTTP status message \\(e\\.g\\. \"Not Found\", \"Internal Server Error\"\\) for non-2xx responses","errorType":"http","errorClass":"ApiError","httpStatus":null,"severity":"error","filePath":"backend/windmill-runtime-nativets/src/windmill-client.js","lineNumber":3598,"sourceCode":"    429: \"Too Many Requests\",\n    431: \"Request Header Fields Too Large\",\n    451: \"Unavailable For Legal Reasons\",\n    500: \"Internal Server Error\",\n    501: \"Not Implemented\",\n    502: \"Bad Gateway\",\n    503: \"Service Unavailable\",\n    504: \"Gateway Timeout\",\n    505: \"HTTP Version Not Supported\",\n    506: \"Variant Also Negotiates\",\n    507: \"Insufficient Storage\",\n    508: \"Loop Detected\",\n    510: \"Not Extended\",\n    511: \"Network Authentication Required\",\n    ...options.errors,\n  };\n  const error = errors[result.status];\n  if (error) {\n    throw new ApiError(options, result, error);\n  }\n  if (!result.ok) {\n    const errorStatus = result.status ?? \"unknown\";\n    const errorStatusText = result.statusText ?? \"unknown\";\n    const errorBody = (() => {\n      try {\n        return JSON.stringify(result.body, null, 2);\n      } catch (e) {\n        return void 0;\n      }\n    })();\n    throw new ApiError(\n      options,\n      result,\n      `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}`\n    );\n  }\n};","sourceCodeStart":3580,"sourceCodeEnd":3616,"githubUrl":"https://github.com/windmill-labs/windmill/blob/e474e8803ce2ff5c2df09a58dab51d45f5c922ca/backend/windmill-runtime-nativets/src/windmill-client.js#L3580-L3616","documentation":"This generated OpenAPI client (windmill-client.js) maps known HTTP status codes to their reason phrases (\"Not Found\", \"Internal Server Error\", etc., extendable via options.errors) and throws an ApiError carrying the full response whenever the server returns a non-2xx status with a mapped message. It is the client's way of surfacing that the Windmill API rejected the request at the HTTP level.","triggerScenarios":"Any windmill-client SDK call (e.g. getJob, runScript, listWorkspaces) whose fetch receives a non-2xx response with a status in the errors map: 404 for a missing script/job/workspace, 401/403 for bad token or permissions, 409 conflicts, 429 rate limits, 5xx server errors.","commonSituations":"Wrong workspace id in the path, an expired or revoked Windmill token, referencing a script path that doesn't exist, requesting a job that was purged, or the server returning 500 during an internal failure.","solutions":["Read error.response.status and .body to identify the actual cause (auth vs not-found vs server error).","For 401/403, refresh the Windmill token (WM_TOKEN) and check the token's workspace/permissions.","For 404, verify the script/job path or id and that the baseUrl points at the correct instance.","For 5xx/429, retry with backoff; check the Windmill server logs for the underlying failure."],"exampleFix":"// before\nconst job = await client.getJob({ workspace, id });\n// after\ntry {\n  const job = await client.getJob({ workspace, id });\n} catch (e) {\n  if (e instanceof ApiError && e.status === 404) {\n    console.error(`Job ${id} not found in workspace ${workspace}`);\n  } else {\n    throw e;\n  }\n}","handlingStrategy":"try-catch","validationCode":"if (!token) throw new Error('WM_TOKEN missing before calling Windmill API');\nif (!workspace) throw new Error('workspace id missing');","typeGuard":"function isApiError(e) { return e instanceof ApiError && typeof e.status === 'number'; }","tryCatchPattern":"try {\n  const res = await client.getJob({ workspace, id });\n} catch (e) {\n  if (isApiError(e)) {\n    switch (e.status) {\n      case 401: case 403: return refreshTokenAndRetry();\n      case 404: return handleNotFound(id);\n      default: if (e.status >= 500 || e.status === 429) return retryWithBackoff();\n    }\n  }\n  throw e;\n}","preventionTips":["Check error.response.status/body rather than the message text before branching.","Rotate Windmill tokens before expiry and verify workspace ids in config.","Add retry-with-backoff for 429/5xx only."],"tags":["http","api-client","status-code","network"],"backgroundTag":"http-non-2xx-response","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"}