{"record":{"id":"eba2714901565471","repo":"jackwener/OpenCLI","slug":"could-not-write-midjourney-media-filepath-er","errorCode":null,"errorMessage":"Could not write Midjourney media ${filePath}: ${errorMessage(error)}","messagePattern":"Could not write Midjourney media (.+?): (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/midjourney/utils.js","lineNumber":707,"sourceCode":"export async function downloadOriginals(page, jobId, indices, outputDir, force = false) {\n  await fs.mkdir(outputDir, { recursive: true });\n  const files = [];\n  for (const index of indices) files.push(await downloadOne(page, jobId, index, outputDir, force));\n  return files;\n}\n\nexport function rawVideoUrl(jobId, index) {\n  return `${MIDJOURNEY_CDN}/video/${jobId}/${index}.mp4`;\n}\n\nasync function writeMediaBuffer(filePath, buffer) {\n  const tempPath = `${filePath}.part-${process.pid}-${Date.now()}`;\n  try {\n    await fs.writeFile(tempPath, buffer);\n    await fs.rename(tempPath, filePath);\n  } catch (error) {\n    await fs.unlink(tempPath).catch(() => {});\n    throw new CommandExecutionError(`Could not write Midjourney media ${filePath}: ${errorMessage(error)}`);\n  }\n}\n\nexport async function downloadRawVideo(page, jobId, index, outputDir, force = false) {\n  await fs.mkdir(outputDir, { recursive: true });\n  const url = rawVideoUrl(jobId, index);\n  const filePath = path.join(outputDir, `${jobId}_${index + 1}_raw.mp4`);\n  const existing = await existingMedia(filePath, force, 'video/mp4');\n  if (existing) return { index, kind: 'video-raw', filePath, bytes: existing.size, url, mime: 'video/mp4', cached: true };\n  const media = await fetchMediaThroughPage(page, url, 'video/');\n  const actualMime = sniffMediaMime(media.buffer);\n  if (actualMime !== 'video/mp4') {\n    throw new CommandExecutionError(`Midjourney raw video returned invalid MP4 bytes from ${url}`);\n  }\n  if (media.mime !== actualMime) {\n    log.warn(`Midjourney CDN reported ${media.mime || 'unknown'} for ${url}; detected ${actualMime} from file bytes`);\n  }\n  await writeMediaBuffer(filePath, media.buffer);","sourceCodeStart":689,"sourceCodeEnd":725,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/midjourney/utils.js#L689-L725","documentation":"Same as the image variant: writing the media bytes (video/other) to filePath failed at the OS level during the temp-file write or atomic rename. The .part temp file is removed before throwing a CommandExecutionError with the underlying reason.","triggerScenarios":"Disk full while writing a large video (ENOSPC); permission denied in the output directory; rename across filesystems; path is a directory or locked by another process.","commonSituations":"Videos are large, so disk-quota exhaustion is more common here than for images; shared network mounts with flaky write support; output directories created with wrong ownership in containers.","solutions":["Free disk space (videos are large; ENOSPC is the most common cause).","Verify the output directory exists and is writable.","Fix permissions/ownership of the output directory.","Ensure the destination filesystem supports atomic rename on the same mount as the temp file."],"exampleFix":"// before\nawait downloadRawVideo(page, jobId, 0, fullDiskDir);\n// after\nawait ensureFreeSpace(dir, requiredBytes);\nawait downloadRawVideo(page, jobId, 0, dir);","handlingStrategy":"validation","validationCode":"import fs from 'node:fs/promises';\nawait fs.mkdir(outputDir, { recursive: true });\nawait fs.access(outputDir, fs.constants.W_OK);","typeGuard":null,"tryCatchPattern":"try {\n  await downloadRawVideo(page, jobId, index, outDir);\n} catch (err) {\n  if (/Could not write Midjourney media/.test(err.message)) {\n    if (err.message.includes('ENOSPC')) throw new Error('Disk full: free space before retry');\n    await fs.mkdir(outDir, { recursive: true });\n    await downloadRawVideo(page, jobId, index, outDir);\n  } else throw err;\n}","preventionTips":["Videos are large; monitor free disk space before downloads.","Ensure the output directory exists and is writable by the running user.","Keep temp files and final files on the same filesystem so rename is atomic.","Handle ENOSPC distinctly; it will recur until space is freed."],"tags":["filesystem","io","write-failure","video","midjourney"],"backgroundTag":"file-write-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}