jackwener/OpenCLI · error · CommandExecutionError

Could not submit the Midjourney prompt: ${error instanceof E

Error message

Could not submit the Midjourney prompt: ${error instanceof Error ? error.message : String(error)}

What it means

Wrapping error for any failure during the prompt-submit step: fillText throwing, the fill not being verified, or pressKey('Enter') failing. The original error message is appended after the 'Could not submit the Midjourney prompt: ' prefix and rethrown as CommandExecutionError, so the CLI never leaves the composer in an unknown half-submitted state without explanation.

Source

Thrown at clis/midjourney/generate.js:196

    }
    await closeImagePanel(page);

    let captureReady = false;
    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,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Read the suffix after the colon — it names the underlying cause (fill failure, verification failure, keypress failure)
  2. Re-run the command; most causes are transient UI races
  3. Confirm the Chrome session is signed in and the Imagine page is stable/idle before retrying
  4. If persistent, update opencli in case Midjourney changed the composer behavior
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-checks before generate:
await page.wait({ selector: COMPOSER_SELECTOR, timeout: 12 });  // composer present and stable
dismissOverlays(page);                                          // no modals stealing focus

Type guard

function isPromptSubmitError(err) {
  return err instanceof Error && err.message.startsWith('Could not submit the Midjourney prompt:');
}

Try / catch

try {
  rows = await generate(prompt, opts);
} catch (e) {
  if (isPromptSubmitError(e)) {
    const cause = e.message.split(': ').slice(1).join(': '); // underlying reason
    console.error(`Submit failed (${cause}); retrying once`);
    rows = await generate(prompt, opts);
  } else throw e;
}

Prevention

When it happens

Trigger: Any exception inside the try block at generate.js:191-197: page.fillText throws (element missing/detached/timeout), the fill result fails the filled/verified check (see index 2617), or page.pressKey('Enter') fails. The caught error's message becomes the suffix of this message.

Common situations: Composer removed by a page re-render mid-fill; Enter keypress blocked by an overlay; browser tab closed or navigated by the user during the command; session expired so the SPA logs out between composer detection and fill.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/c384a7aeb76ed29e. Report an issue: GitHub.