{"record":{"id":"1fa67514d120b85d","repo":"jackwener/OpenCLI","slug":"midjourney-job-submission","errorCode":null,"errorMessage":"Midjourney job submission","messagePattern":"Midjourney job submission","errorType":"exception","errorClass":"TimeoutError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/generate.js","lineNumber":200,"sourceCode":"    if (typeof page.installInterceptor === 'function' && typeof page.getInterceptedRequests === 'function') {\n      try {\n        await page.installInterceptor('/api/submit-jobs');\n        await page.getInterceptedRequests();\n        captureReady = true;\n      } catch {}\n    }\n\n    const submittedAt = Date.now();\n    try {\n      const filled = await page.fillText(COMPOSER_SELECTOR, effectivePrompt);\n      if (!filled?.filled || !filled?.verified) throw new Error('composer fill was not verified');\n      await page.pressKey('Enter');\n    } catch (error) {\n      throw new CommandExecutionError(`Could not submit the Midjourney prompt: ${error instanceof Error ? error.message : String(error)}`);\n    }\n\n    const remainingForSubmission = Math.floor(timeout - (Date.now() - commandStartedAt) / 1000);\n    if (remainingForSubmission < 1) throw new TimeoutError('Midjourney job submission', timeout);\n    const submitTimeout = Math.min(remainingForSubmission, 75);\n    let jobIds = [];\n    if (captureReady && typeof page.waitForCapture === 'function') {\n      try {\n        await page.waitForCapture(Math.min(submitTimeout, 20));\n        jobIds = submittedJobIdsFromCaptures(await page.getInterceptedRequests(), plan.repeat, baselineIds);\n      } catch (error) {\n        if (error instanceof CommandExecutionError) throw error;\n      }\n    }\n    if (!jobIds.length) {\n      jobIds = await waitForSubmittedJobsAfter(\n        page,\n        account.user_id,\n        effectivePrompt,\n        baselineIds,\n        submitTimeout,\n        submittedAt,","sourceCodeStart":182,"sourceCodeEnd":218,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/generate.js#L182-L218","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nopencli midjourney generate \"prompt\" --image-ref ./big.png --timeout 30\n// after\nopencli midjourney generate \"prompt\" --image-ref ./big.png --timeout 600","handlingStrategy":"validation","validationCode":"const TIMEOUT = 600; // seconds\nconst largeLocalRefs = [imageRef, ...styleRefs].filter((p) => !/^https?:/.test(p));\nconst totalMb = largeLocalRefs.reduce((s, p) => s + fs.statSync(p).size / 1e6, 0);\n// Rough guard: uploads+setup need headroom before submission can be confirmed.\nif (totalMb > 20 && TIMEOUT < 300) {\n  throw new Error(`--timeout ${TIMEOUT}s too small for ${totalMb.toFixed(0)}MB of reference uploads; use >= 600`);\n}","typeGuard":"function willLikelyTimeOut(timeoutSeconds, uploadBytes) {\n  const setupSeconds = 30 + (uploadBytes / (2 * 1024 * 1024)); // ~2 MB/s heuristic\n  return timeoutSeconds <= setupSeconds + 45; // +45s submission-confirmation window\n}","tryCatchPattern":"try {\n  await generate(prompt, { timeout: 600 });\n} catch (e) {\n  if (/Midjourney job submission/.test(e.message) || e.name === 'TimeoutError') {\n    // Submission may or may not have gone through — check history before resubmitting\n    const dupes = await fetchRecentJobs(prompt);\n    if (!dupes.length) await generate(prompt, { timeout: 900, wait: false });\n  } else throw e;\n}","preventionTips":["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"],"tags":["timeout","midjourney","browser-automation","budget"],"backgroundTag":"operation-timeout","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}