windmill-labs/windmill · error · Error
GET ${path} -> ${response.status}: ${body}
Error message
GET ${path} -> ${response.status}: ${body} What it means
Generic API error thrown by apiGet, the helper behind read-only `wmill pipeline` subcommands (list, show, etc.). Any non-OK response from `GET {OpenAPI.BASE}{path}` is converted into an Error carrying the request path, HTTP status, and response body, replacing the default fetch behavior of silently resolving.
Source
Thrown at cli/src/commands/pipeline/pipeline.ts:71
// GraphTrigger) are defined in ./localGraph.ts — the canonical pipeline graph
// module — and shared by the local (wasm-built) and deployed (apiGet) paths.
//
// Mirrors the asset-graph endpoint payload (backend/windmill-api-assets).
// TODO: the checked-in generated client (cli/gen, last regenerated 2025-04)
// predates these routes, so we raw-fetch and hand-roll the types. Once
// `cli/gen` is regenerated (run `cli/gen_wm_client.sh`, which is currently
// >700 openapi.yaml commits stale and would churn the whole client), replace
// `apiGet` + these types with the generated `wmill.getAssetsGraph(...)`
// (operationId getAssetsGraph) and `wmill.listPipelineFolders(...)`
// (operationId listPipelineFolders).
async function apiGet<T>(path: string): Promise<T> {
const response = await fetch(`${OpenAPI.BASE}${path}`, {
headers: { Authorization: `Bearer ${OpenAPI.TOKEN}` },
});
if (!response.ok) {
const body = await response.text();
throw new Error(`GET ${path} -> ${response.status}: ${body}`);
}
return (await response.json()) as T;
}
async function list(opts: GlobalOptions & { json?: boolean }) {
if (opts.json) log.setSilent(true);
const workspace = await resolveWorkspace(opts);
await requireLogin(opts);
const items = await apiGet<{ folder: string; script_count: number }[]>(
`/w/${workspace.workspaceId}/assets/pipelines`,
);
if (opts.json) {
console.log(JSON.stringify(items));
} else if (items.length === 0) {
log.info(
"No pipelines in this workspace. Mark scripts with a `// pipeline` comment (plus `// on <spec>` triggers) and push them into a folder.",
);View on GitHub (pinned to e474e8803c)
Solutions
- Inspect status in the message: 401/403 -> run `wmill auth login` or fix WMILL_TOKEN/workspace.
- 404 -> verify the pipeline/script path and workspace id (`wmill workspace list`).
- Confirm the base URL with curl: `curl -H "Authorization: Bearer $WMILL_TOKEN" $WMILL_BASE_URL<path>` to reproduce outside the CLI.
- 5xx -> check server health/logs, then retry; if behind a proxy, verify it forwards Authorization headers.
Example fix
// before: hitting wrong instance wmill pipeline list # -> GET /w/.../pipelines -> 404: ... // after wmill workspace switch <correct-workspace> wmill pipeline list
Defensive patterns
Strategy: try-catch
Validate before calling
// Pre-flight: verify auth and base URL before calling pipeline subcommands
const res = await fetch(`${OpenAPI.BASE}/users/me`, {
headers: { Authorization: `Bearer ${OpenAPI.TOKEN}` },
});
if (!res.ok) throw new Error(`Auth/base-url check failed: ${res.status}`); Try / catch
try {
const items = await apiGet<Pipeline[]>(`/w/${ws}/pipelines/list`);
} catch (e: any) {
const m = /-> (\d{3}):/.exec(e.message);
switch (m?.[1]) {
case "401": case "403": console.error("Run `wmill auth login`"); break;
case "404": console.error("Unknown path/workspace — check `wmill workspace list`"); break;
default: console.error("Server error — check instance health");
}
throw e;
} Prevention
- Always `wmill auth login` before scripted use, and verify with `wmill workspace show`.
- Quote pipeline paths exactly as shown in the UI (workspace-relative, no leading slash confusion).
- Check the base URL points at the intended instance when working with multiple worktrees.
When it happens
Trigger: Any `wmill pipeline <subcommand>` where the backend returns 401 (missing/expired token), 404 (unknown pipeline/script path), 400 (malformed path), or 5xx; also when OpenAPI.BASE is misconfigured and hits the wrong host (404/502 from a proxy).
Common situations: Running without `wmill auth login` first; pipeline path with a typo or wrong workspace; targeting a self-hosted instance through a reverse proxy that mangles the path; server temporarily down returning 502.
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
- Couldn't fetch resource types from hub ${hubBaseUrl}: ${(awa
- Couldn't fetch resource types from public hub:
- GET assets/graph -> ${res.status}: ${await res.text()}
- Preview failed: ${response.status} - ${response.statusText}
- Got an HTML response from ${url} (status ${status}${cfPart ?
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/26ba48030c7fde7a.
Report an issue: GitHub.