windmill-labs/windmill · error · LockfileGenerationError
Failed to queue dependencies job: ${queueResponse.status} ${
Error message
Failed to queue dependencies job: ${queueResponse.status} ${queueResponse.statusText}, ${bodyText} What it means
fetchScriptLock queues a `dependencies_async` job on the Windmill server to generate a script's lockfile remotely. This LockfileGenerationError is thrown when the HTTP POST that queues that job returns a non-2xx status; the server's HTTP status, status text and response body are embedded in the message so the underlying API rejection is visible. It is the CLI's way of surfacing a server-side or network-level rejection of the lockfile-generation request before any job is even created.
Source
Thrown at cli/src/utils/metadata.ts:643
? rawWorkspaceDependencies : null,
entrypoint: remotePath,
temp_script_refs: tempScriptRefs && Object.keys(tempScriptRefs).length > 0
? tempScriptRefs : null,
}),
}
);
await detectAuthGatewayChallenge(
queueResponse,
`${workspace.remote}api/w/${workspace.workspaceId}/jobs/run/dependencies_async`,
);
if (!queueResponse.ok) {
let bodyText = "";
try {
bodyText = await queueResponse.text();
} catch { /* ignore */ }
throw new LockfileGenerationError(
`Failed to queue dependencies job: ${queueResponse.status} ${queueResponse.statusText}, ${bodyText}`
);
}
const jobId = (await queueResponse.text()).trim();
let completion;
try {
completion = await pollJobWithQueueLogging(
workspace.workspaceId,
jobId,
{ label: `deps ${remotePath}` },
);
} catch (e: any) {
throw new LockfileGenerationError(
`Failed to poll dependencies job ${jobId}: ${e?.message ?? e}`
);
}View on GitHub (pinned to e474e8803c)
Solutions
- Run `wmill workspace switch` (or re-add the workspace with a fresh token) to fix expired/invalid credentials, then retry
- Verify the workspace remote URL points at the Windmill API root and not through an SSO gateway or proxy that injects HTML (check `wmill workspace` list)
- Confirm the workspace id and your token's permissions (the token must be allowed to run jobs in that workspace)
- Check the Windmill server is healthy and workers are running (status endpoint / instance admin); retry after transient 5xx
- Read the bodyText portion of the message — it contains the server's JSON error explaining the exact rejection
Example fix
// before: raw fetch failing with opaque error
const res = await fetch(url, { method: "POST", headers, body });
// after: pre-validate auth and surface actionable message
const res = await fetch(url, { method: "POST", headers, body });
if (res.status === 401 || res.status === 403) {
throw new LockfileGenerationError(
`Token rejected by ${workspace.remote} (${res.status}); run 'wmill workspace switch' to refresh credentials`
);
} Defensive patterns
Strategy: try-catch
Validate before calling
// pre-flight: verify the workspace token is accepted before queueing
const who = await fetch(`${workspace.remote}api/users/whoami`, {
headers: { Cookie: `token=${workspace.token}` },
});
if (!who.ok) {
throw new Error(
`Workspace token invalid for ${workspace.workspaceId} (HTTP ${who.status}); run 'wmill workspace switch' first`
);
} Type guard
function isOkResponse(res: Response): res is Response & { ok: true } {
return res.ok;
}
// usage:
// if (!isOkResponse(queueResponse)) { handle non-2xx safely } Try / catch
try {
const lock = await fetchScriptLock(workspace, content, language, path, deps);
} catch (e) {
if (e instanceof LockfileGenerationError && e.message.includes("Failed to queue dependencies job: 401")) {
log.error("Token rejected — refresh credentials with `wmill workspace switch`");
} else if (e instanceof LockfileGenerationError && / 5\d\d /.test(e.message)) {
log.error("Windmill server error — retry shortly");
} else {
throw e;
}
} Prevention
- Refresh workspace tokens regularly and before long sync/push operations (`wmill workspace switch`)
- Check `wmill workspace` shows the correct remote and workspace id before pushing
- Avoid routing the remote through SSO gateways/proxies that rewrite API responses
- Monitor instance health (workers running) when pushing large dependency sets
- Always read the bodyText in the error — it carries the server's exact rejection reason
When it happens
Trigger: Any non-ok response from POST {remote}/api/w/{workspaceId}/jobs/run/dependencies_async: invalid/expired workspace token (401), missing permissions on the workspace (403), unknown workspace id (404), malformed request payload (422), worker/queue unavailable or server error (5xx), or a proxy/gateway intercepting the request with an HTML error page.
Common situations: Stale WM_TOKEN after token rotation or logout; pointing `remote` at a reverse proxy or SSO gateway that returns a login/HTML page instead of the API; wrong workspace id in workspace config; Windmill server temporarily down or overloaded (502/503 from load balancer); enterprise ACLs denying the 'dependencies_async' endpoint.
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()}
- GET ${path} -> ${response.status}: ${body}
- Preview failed: ${response.status} - ${response.statusText}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/e59b6a32152b8fac.
Report an issue: GitHub.