windmill-labs/windmill · error · LockfileGenerationError
Failed to generate lockfile: ${JSON.stringify(result, null,
Error message
Failed to generate lockfile: ${JSON.stringify(result, null, 2)} What it means
The dependencies job succeeded (completion.success === true) but its result did not contain a `lock` field, so there is no lockfile to return. The CLI throws this LockfileGenerationError with the full JSON-dumped result so you can inspect what the job actually produced. This indicates a contract mismatch between the job's output shape and what the CLI expects.
Source
Thrown at cli/src/utils/metadata.ts:673
{ label: `deps ${remotePath}` },
);
} catch (e: any) {
throw new LockfileGenerationError(
`Failed to poll dependencies job ${jobId}: ${e?.message ?? e}`
);
}
const result = completion.result as any;
if (!completion.success) {
const message =
result?.error?.message ??
(typeof result === "string" ? result : JSON.stringify(result, null, 2));
throw new LockfileGenerationError(`Failed to generate lockfile: ${message}`);
}
const lock = result?.lock;
if (lock === undefined) {
throw new LockfileGenerationError(
`Failed to generate lockfile: ${JSON.stringify(result, null, 2)}`
);
}
if (cacheKey) {
lockCache.set(cacheKey, lock);
}
return lock;
}
async function updateScriptLock(
workspace: Workspace,
scriptContent: string,
language: ScriptLanguage,
remotePath: string,
metadataContent: Record<string, any>,
rawWorkspaceDependencies: Record<string, string>,
tempScriptRefs?: Record<string, string>,
lockPathOverride?: string,View on GitHub (pinned to e474e8803c)
Solutions
- Upgrade or align the wmill CLI version with your server version (`wmill version` vs instance version; `npm i -g windmill-cli@latest`)
- Inspect the JSON in the message to see what the job returned and whether `lock` is nested under a different key
- Check for self-hosted modifications to the dependencies_async job that change its result shape
- If behind a mock/gateway, fix the stub to return { success: true, result: { lock: "..." } }
- Work around locally by committing the lockfile directly and skipping remote generation, then report the version mismatch
Example fix
// before: server returns success without lock, CLI fails
{"success": true, "result": {"ok": true}}
// after: align server/CLI so result carries the lock
{"success": true, "result": {"lock": "numpy==1.26.4\n..."}} Defensive patterns
Strategy: type-guard
Validate before calling
// validate the expected job result shape before using it
function looksLikeLockResult(result: any): boolean {
return result != null && typeof result === "object" && typeof result.lock === "string";
} Type guard
function hasLock(
result: any,
): result is { lock: string } {
return (
result != null &&
typeof result === "object" &&
typeof result.lock === "string" &&
result.lock.length > 0
);
} Try / catch
try {
const lock = await fetchScriptLock(workspace, content, language, path, deps);
} catch (e) {
if (e instanceof LockfileGenerationError && e.message.includes("{\"")) {
log.error(
"Dependencies job returned no lock payload — likely CLI/server version mismatch. " +
"Run `wmill version` and align the CLI with your instance, or inspect the returned JSON: " + e.message
);
} else throw e;
} Prevention
- Keep the wmill CLI version in sync with your Windmill server version
- After upgrading either side, re-run a small push to verify the job result contract still holds
- Watch for self-hosted modifications to the dependencies_async job that change its result shape
- Commit lockfiles to the repo so a failed remote generation is non-blocking
When it happens
Trigger: The job result lacks result.lock — e.g. an older/newer Windmill server whose dependencies job returns a different result shape, a job that returned success with an empty/partial payload, or a proxy mocking the API returning {"success": true} without the lock payload.
Common situations: CLI and server version skew (CLI expecting a `lock` field the deployed server's dependency job doesn't emit); custom/self-hosted patches to the dependencies job; a stubbed API gateway used in tests returning a success result without a lock.
Related errors
- Failed to generate lockfile: ${message}
- Cannot regenerate lock for flow ${remote_path}: missing inli
- Failed to queue flow dependencies job: ${queueResponse.statu
- Failed to poll flow dependencies job ${jobId}: ${e?.message
- Failed to generate lockfile: ${message}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/fa974a0f8ee4f672.
Report an issue: GitHub.