{"record":{"id":"c4687d192a4fc532","repo":"jackwener/OpenCLI","slug":"midjourney-submission-is-ambiguous-ambiguousids","errorCode":null,"errorMessage":"Midjourney submission is ambiguous; ${ambiguousIds.length} new jobs matched the prompt","messagePattern":"Midjourney submission is ambiguous; (.+?) new jobs matched the prompt","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":462,"sourceCode":"    });\n    const matching = newRows.filter((row) => {\n      const candidate = promptFromFullCommand(row.full_command);\n      return candidate === expected || (\n        expectedCore\n        && promptCore(candidate) === expectedCore\n        && promptKeySignature(candidate) === expectedSignature\n      );\n    });\n    if (matching.length === expectedCount) {\n      return [...matching]\n        .sort((left, right) => Date.parse(left.enqueue_time) - Date.parse(right.enqueue_time))\n        .map((row) => String(row.id).toLowerCase());\n    }\n    if (matching.length > expectedCount) ambiguousIds = matching.map((row) => String(row.id).toLowerCase());\n    if (!(await waitForNextPoll(page, deadline, 1.5))) break;\n  } while (true);\n  if (ambiguousIds.length > expectedCount) {\n    throw new CommandExecutionError(\n      `Midjourney submission is ambiguous; ${ambiguousIds.length} new jobs matched the prompt`,\n      ambiguousIds.map((id) => jobUrl(id)).join(', '),\n    );\n  }\n  throw new TimeoutError(\n    'Midjourney job submission',\n    timeoutSeconds,\n    `Expected ${expectedCount} uniquely matched job(s) after submission.`,\n  );\n}\n\nexport async function waitForDerivedJob(page, userId, parentJobId, baselineIds, timeoutSeconds, submittedAtMs) {\n  const deadline = Date.now() + timeoutSeconds * 1000;\n  let candidates = [];\n  let consecutivePollFailures = 0;\n  do {\n    let recent;\n    try {","sourceCodeStart":444,"sourceCodeEnd":480,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L444-L480","documentation":"During submit-and-wait polling, the library tracks IDs of new jobs matching the submitted prompt. If more new jobs than expected match, the submission result is ambiguous and CommandExecutionError is thrown with the count and URLs of the ambiguous jobs. This prevents operating on the wrong job when the user (or a parallel session) submitted similar prompts concurrently.","triggerScenarios":"Calling the submit flow when expectedCount new jobs matched the prompt within the polling window but matching.length exceeds expectedCount — e.g. duplicate submissions, a concurrent session sending the same /imagine prompt, or prompt text matching existing in-flight jobs.","commonSituations":"Double-submitting due to CLI retries without dedup; running two CLI sessions with the same prompt; using a very generic prompt that matches unrelated queued jobs within the 5s/poll matching window.","solutions":["Check the job URLs in the error, pick the intended one manually, and track/wait on that specific job ID instead of re-submitting.","Use a more distinctive prompt text so matching is unique.","Ensure no other session/process is submitting the same prompt concurrently.","Rerun the command once the unrelated jobs finish, so only the new submission matches."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// avoid duplicate submissions and generic prompts before running the submit flow\nconst recent = await fetchJobStatuses(page, recentJobIds).catch(() => []);\nconst inFlightSimilar = recent.filter((j) =>\n  String(j.prompt || '').includes(promptCoreText) && !isTerminal(j)\n);\nif (inFlightSimilar.length > 0) {\n  throw new Error(`${inFlightSimilar.length} similar job(s) already in flight; wait or track them by ID instead of resubmitting.`);\n}","typeGuard":null,"tryCatchPattern":"try {\n  await submitAndAwait(page, prompt, { expectedCount: 1 });\n} catch (e) {\n  const m = String(e.message).match(/ambiguous; (\\d+) new jobs/);\n  if (m) {\n    console.error('Pick the intended job from the URLs in the error and track it by ID instead of resubmitting.');\n  } else throw e;\n}","preventionTips":["Never retry a timed-out submission without first checking whether the job was created","Use distinctive prompt text so new-job matching is unique","Run one CLI session per account to avoid concurrent identical submissions","Track job IDs explicitly instead of prompt-based matching when possible"],"tags":["midjourney","ambiguity","polling"],"backgroundTag":"ambiguous-job-match","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}