{"record":{"id":"d8b13dd26abc1dcf","repo":"jackwener/OpenCLI","slug":"job-id-must-be-a-midjourney-uuid-or-https-www-mi","errorCode":null,"errorMessage":"job-id must be a Midjourney UUID or https://www.midjourney.com/jobs/<uuid> URL","messagePattern":"job-id must be a Midjourney UUID or https://www\\.midjourney\\.com/jobs/<uuid> URL","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":71,"sourceCode":"    throw new ArgumentError(`${label} must be a positive integer`);\n  }\n  if (parsed > max) {\n    throw new ArgumentError(`${label} must be <= ${max}`);\n  }\n  return parsed;\n}\n\nexport function parseJobId(value) {\n  const raw = String(value ?? '').trim();\n  if (UUID_RE.test(raw)) return raw.toLowerCase();\n  try {\n    const parsed = new URL(raw);\n    const match = parsed.pathname.match(/^\\/jobs\\/([0-9a-f-]{36})\\/?$/i);\n    if (parsed.protocol === 'https:' && parsed.hostname === MIDJOURNEY_DOMAIN && match && UUID_RE.test(match[1])) {\n      return match[1].toLowerCase();\n    }\n  } catch {}\n  throw new ArgumentError(\n    'job-id must be a Midjourney UUID or https://www.midjourney.com/jobs/<uuid> URL',\n    'Example: opencli midjourney status d5664250-5f1f-4cd0-9637-2ce0153dd30a',\n  );\n}\n\nexport function parseImageIndices(value, batchSize = 4) {\n  const max = Number.isInteger(batchSize) && batchSize > 0 ? batchSize : 4;\n  const raw = String(value ?? 'all').trim().toLowerCase();\n  if (!raw || raw === 'all') return Array.from({ length: max }, (_, index) => index);\n  if (!/^\\d+$/.test(raw)) {\n    throw new ArgumentError(`--index must be \"all\" or an integer from 1 to ${max}`);\n  }\n  const userIndex = Number(raw);\n  if (userIndex < 1 || userIndex > max) {\n    throw new ArgumentError(`--index must be between 1 and ${max} for this job`);\n  }\n  return [userIndex - 1];\n}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L53-L89","documentation":"parseJobId normalizes a job identifier for commands like `midjourney status`. It accepts either a bare 36-character UUID or a https://www.midjourney.com/jobs/<uuid> URL and throws this ArgumentError when the input is neither. The URL path must match /jobs/<uuid> exactly and the UUID must pass UUID_RE.","triggerScenarios":"Passing a non-https URL, a midjourney.com URL whose path is not /jobs/<uuid> (e.g. a gallery or imagine page link), a shortened/partial id, an id containing invalid characters, or an empty/whitespace value.","commonSituations":"Pasting the wrong link from the Midjourney web app (showcase or feed URL instead of a job URL), copying a URL with query strings and expecting the parser to strip them, trimming the UUID by accident, or using an http:// link.","solutions":["Copy the UUID directly from a valid job URL (the 36-char hex-dash segment after /jobs/) and pass just that","Ensure a URL input is exactly https://www.midjourney.com/jobs/<uuid> with no extra path segments or query string","Check for typos/truncation in the UUID (must be 8-4-4-4-12 hex characters)","Re-run the generation to obtain a fresh job id if the original is unavailable"],"exampleFix":"// before\nopencli midjourney status \"https://www.midjourney.com/imagine/a-blue-teapot-123\"\n// after\nopencli midjourney status d5664250-5f1f-4cd0-9637-2ce0153dd30a","handlingStrategy":"validation","validationCode":"const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\nfunction extractJobId(input) {\n  const raw = String(input ?? '').trim();\n  if (UUID_RE.test(raw)) return raw.toLowerCase();\n  try {\n    const u = new URL(raw);\n    const m = u.pathname.match(/^\\/jobs\\/([0-9a-f-]{36})\\/?$/i);\n    if (u.protocol === 'https:' && u.hostname === 'www.midjourney.com' && m && UUID_RE.test(m[1]))\n      return m[1].toLowerCase();\n  } catch {}\n  throw new Error('Not a valid Midjourney job id or /jobs/ URL');\n}","typeGuard":"function isJobIdLike(v) {\n  return typeof v === 'string' && /^[0-9a-f-]{36}$/i.test(v.trim());\n}","tryCatchPattern":"try {\n  const id = extractJobId(input);\n  await status(id);\n} catch (err) {\n  if (err.name === 'ArgumentError' && /job-id/.test(err.message)) {\n    console.error('Pass a UUID or a https://www.midjourney.com/jobs/<uuid> URL');\n    process.exitCode = 2;\n  } else throw err;\n}","preventionTips":["Copy the UUID segment from the /jobs/ URL rather than the whole link","Avoid gallery/showcase URLs — only /jobs/<uuid> links are accepted","Strip query strings and fragments before passing URLs","Store job ids as plain UUIDs in scripts"],"tags":["cli","argument-validation","url-parsing","midjourney"],"backgroundTag":"invalid-job-id-format","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}