jackwener/OpenCLI · error · TimeoutError
Midjourney job submission
Error message
Midjourney job submission
What it means
TimeoutError thrown when the overall --timeout budget (default 300s, max 900s) is exhausted before the job could even be confirmed as submitted — i.e. remainingForSubmission computed from (Date.now() - commandStartedAt) drops below 1 second right after pressing Enter. The name 'Midjourney job submission' indicates the deadline hit during the submission-confirmation phase, not during generation.
Source
Thrown at clis/midjourney/generate.js:200
if (typeof page.installInterceptor === 'function' && typeof page.getInterceptedRequests === 'function') {
try {
await page.installInterceptor('/api/submit-jobs');
await page.getInterceptedRequests();
captureReady = true;
} catch {}
}
const submittedAt = Date.now();
try {
const filled = await page.fillText(COMPOSER_SELECTOR, effectivePrompt);
if (!filled?.filled || !filled?.verified) throw new Error('composer fill was not verified');
await page.pressKey('Enter');
} catch (error) {
throw new CommandExecutionError(`Could not submit the Midjourney prompt: ${error instanceof Error ? error.message : String(error)}`);
}
const remainingForSubmission = Math.floor(timeout - (Date.now() - commandStartedAt) / 1000);
if (remainingForSubmission < 1) throw new TimeoutError('Midjourney job submission', timeout);
const submitTimeout = Math.min(remainingForSubmission, 75);
let jobIds = [];
if (captureReady && typeof page.waitForCapture === 'function') {
try {
await page.waitForCapture(Math.min(submitTimeout, 20));
jobIds = submittedJobIdsFromCaptures(await page.getInterceptedRequests(), plan.repeat, baselineIds);
} catch (error) {
if (error instanceof CommandExecutionError) throw error;
}
}
if (!jobIds.length) {
jobIds = await waitForSubmittedJobsAfter(
page,
account.user_id,
effectivePrompt,
baselineIds,
submitTimeout,
submittedAt,View on GitHub (pinned to 49907e53dc)
Solutions
- Increase --timeout (up to 900) to leave room for uploads plus submission confirmation
- Reduce upload cost — drop --image-ref/--style-ref/--omni-ref or use HTTPS URLs instead of large local files
- Run with --wait false and --skip-download so the budget is spent only on submission
- Check network speed to midjourney.com; slow uploads are the usual budget consumer
Example fix
// before opencli midjourney generate "prompt" --image-ref ./big.png --timeout 30 // after opencli midjourney generate "prompt" --image-ref ./big.png --timeout 600
Defensive patterns
Strategy: validation
Validate before calling
const TIMEOUT = 600; // seconds
const largeLocalRefs = [imageRef, ...styleRefs].filter((p) => !/^https?:/.test(p));
const totalMb = largeLocalRefs.reduce((s, p) => s + fs.statSync(p).size / 1e6, 0);
// Rough guard: uploads+setup need headroom before submission can be confirmed.
if (totalMb > 20 && TIMEOUT < 300) {
throw new Error(`--timeout ${TIMEOUT}s too small for ${totalMb.toFixed(0)}MB of reference uploads; use >= 600`);
} Type guard
function willLikelyTimeOut(timeoutSeconds, uploadBytes) {
const setupSeconds = 30 + (uploadBytes / (2 * 1024 * 1024)); // ~2 MB/s heuristic
return timeoutSeconds <= setupSeconds + 45; // +45s submission-confirmation window
} Try / catch
try {
await generate(prompt, { timeout: 600 });
} catch (e) {
if (/Midjourney job submission/.test(e.message) || e.name === 'TimeoutError') {
// Submission may or may not have gone through — check history before resubmitting
const dupes = await fetchRecentJobs(prompt);
if (!dupes.length) await generate(prompt, { timeout: 900, wait: false });
} else throw e;
} Prevention
- Always budget --timeout generously (600-900) when uploading local reference files
- Use HTTPS URLs for image/style refs instead of large local files when possible
- Reserve at least ~60s after setup for submission confirmation
- Remember Enter may have been pressed before the deadline — check job history before resubmitting to avoid duplicate paid jobs
- Split many --repeat jobs into separate invocations with their own timeouts
When it happens
Trigger: Uploading local image/style/omni references via uploadReferencesToSlot, waiting for the composer, and clearImagePrompts consumed nearly the entire --timeout before submission was attempted, leaving <1s to confirm the submit-jobs request. Common with large reference files, many --repeat jobs, or a very small --timeout value (e.g. --timeout 10).
Common situations: Users passing --timeout 30 or lower while also uploading several large reference images; slow network uploads to Midjourney's slots; the persistent browser being cold/slow so composer setup ate the budget; retrying a command whose earlier phases were slow.
Related errors
- Midjourney Describe
- Midjourney ${kind} download did not complete: ${downloaded?.
- Unexpected 12306 probe: ${JSON.stringify(probe)}
- ChatGPT did not create a conversation URL after sending the
- ChatWise response
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1fa67514d120b85d.
Report an issue: GitHub.