windmill-labs/windmill · error · Error
Queued jobs file must contain an array of jobs
Error message
Queued jobs file must contain an array of jobs
What it means
Thrown by `wmill job push` (pushJobs) in the Windmill CLI when the queued-jobs file (default queued_jobs.json, overridable with --queued-file) parses as valid JSON but is not a JSON array. The CLI forwards the parsed value directly as the `requestBody` of `wmill.importQueuedJobs`, whose API contract requires a list of queued-job objects, so a non-array body is rejected before any network call.
Source
Thrown at cli/src/commands/jobs/jobs.ts:226
if (e.code === "ENOENT") {
log.info(
colors.yellow(
`No completed jobs file found at ${completedPath}, skipping`
)
);
} else {
throw new Error(`Failed to push completed jobs: ${e}`);
}
}
// Push queued jobs
const queuedPath = opts.queuedFile || "queued_jobs.json";
try {
const queuedContent = await readTextFile(queuedPath);
const queuedJobs = JSON.parse(queuedContent);
if (!Array.isArray(queuedJobs)) {
throw new Error("Queued jobs file must contain an array of jobs");
}
const queuedResult = await wmill.importQueuedJobs({
workspace: ws.workspaceId,
requestBody: queuedJobs,
});
log.info(colors.green(`Queued jobs: ${queuedResult}`));
} catch (e: any) {
if (e.code === "ENOENT") {
log.info(
colors.yellow(`No queued jobs file found at ${queuedPath}, skipping`)
);
} else {
throw new Error(`Failed to push queued jobs: ${e}`);
}
}
}View on GitHub (pinned to e474e8803c)
Solutions
- Open the file and ensure the top-level value is a JSON array: wrap the object(s) in [ ... ].
- If the file wraps jobs in an object like {"jobs": [...]}, extract the inner array into the file.
- If converting from JSONL, merge the newline-delimited objects into a single comma-separated array.
- Re-export the queued jobs with the matching `wmill job pull` command so the file has the canonical array shape.
Example fix
// before (queued_jobs.json)
{"path": "f/my_script", "args": {}}
// after
[{"path": "f/my_script", "args": {}}] Defensive patterns
Strategy: validation
Validate before calling
const jobs = JSON.parse(await readTextFile(queuedPath));
if (!Array.isArray(jobs)) throw new Error(`${queuedPath} must be a JSON array of jobs`); Type guard
function isJobArray(v: unknown): v is Record<string, unknown>[] {
return Array.isArray(v) && v.every((x) => typeof x === "object" && x !== null);
} Try / catch
try {
await wmill.importQueuedJobs({ workspace: ws, requestBody: queuedJobs });
} catch (e) {
if (String(e).includes("must contain an array")) {
console.error(`Fix ${queuedPath}: top level must be [...]`);
}
throw e;
} Prevention
- Always generate queued_jobs.json via `wmill job pull`, never hand-edit the top level.
- Validate the file with `jq 'type == "array"' queued_jobs.json` before pushing.
- Never point --queued-file at a JSONL or wrapper-object export.
When it happens
Trigger: Running `wmill job push` with a queued-jobs file whose top-level JSON value is an object ({...}), a string, a number, or null instead of an array of job objects.
Common situations: The file was hand-edited and the array wrapper was lost; a single job object was exported instead of an array; the file was written by another tool that emits {"jobs": [...]} wrapper objects; a JSONL file (multiple objects, no enclosing array) was pointed at --queued-file.
Related errors
- Completed jobs file must contain an array of jobs
- Invalid migration name '${name}': use only letters, digits,
- Unknown workspace dependencies file format: ${path}. Valid f
- Cannot push flow ${remotePath}: step(s) reference non-worksp
- Failed to push completed jobs: ${e}
AI-assisted analysis of windmill-labs/windmill@e474e8803c (2026-09-03).
Data as JSON: /api/errors/ecc210bec1e79720.
Report an issue: GitHub.