{"record":{"id":"3f6db2b87e30c980","repo":"jackwener/OpenCLI","slug":"cover-image-file-not-found-imagepath","errorCode":null,"errorMessage":"Cover image file not found: ${imagePath}","messagePattern":"Cover image file not found: (.+?)","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/douyin/_shared/imagex-upload.js","lineNumber":36,"sourceCode":"            return 'image/png';\n        case '.gif':\n            return 'image/gif';\n        case '.webp':\n            return 'image/webp';\n        default:\n            return 'image/jpeg';\n    }\n}\n/**\n * Upload a cover image to ByteDance ImageX via a pre-signed PUT URL.\n *\n * @param imagePath - Local file path to the image (JPEG/PNG/etc.)\n * @param uploadInfo - Upload URL and store_uri from the apply cover upload API\n * @returns The store_uri (= image_uri for use in create_v2)\n */\nexport async function imagexUpload(imagePath, uploadInfo) {\n    if (!fs.existsSync(imagePath)) {\n        throw new CommandExecutionError(`Cover image file not found: ${imagePath}`, 'Ensure the file path is correct and accessible.');\n    }\n    const imageBuffer = fs.readFileSync(imagePath);\n    const contentType = detectContentType(imagePath);\n    const res = await fetch(uploadInfo.upload_url, {\n        method: 'PUT',\n        headers: {\n            'Content-Type': contentType,\n            'Content-Length': String(imageBuffer.byteLength),\n        },\n        body: imageBuffer,\n    });\n    if (!res.ok) {\n        const body = await res.text().catch(() => '');\n        throw new CommandExecutionError(`ImageX upload failed with status ${res.status}: ${body}`, 'Check that the upload URL is valid and has not expired.');\n    }\n    return uploadInfo.store_uri;\n}\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/douyin/_shared/imagex-upload.js#L18-L54","documentation":"imagexUpload uploads a local cover image to Douyin's ImageX service. Before reading the file it checks fs.existsSync and throws this CommandExecutionError if the path does not exist, preventing a confusing low-level fs error later.","triggerScenarios":"The imagePath passed to imagexUpload does not exist on disk — wrong relative path, typo, deleted/moved file, or path resolved from a different working directory.","commonSituations":"Running the CLI from a different cwd than expected so relative paths break; cover file deleted between selection and upload; Windows/Unix path separator mistakes; shell quoting dropping part of the path.","solutions":["Verify the file exists at the exact path (ls / Test-Path) and correct the path argument.","Use an absolute path instead of a relative one to avoid cwd dependence.","Re-export or recreate the cover image if it was deleted or moved.","Check for typos and shell-escape spaces in the filename."],"exampleFix":"// before\nawait imagexUpload('cover.png', uploadInfo);\n// after\nimport path from 'node:path';\nimport fs from 'node:fs';\nconst p = path.resolve('cover.png');\nif (!fs.existsSync(p)) throw new Error(`cover missing: ${p}`);\nawait imagexUpload(p, uploadInfo);","handlingStrategy":"validation","validationCode":"import fs from 'node:fs';\nimport path from 'node:path';\nconst abs = path.resolve(imagePath);\nif (!fs.existsSync(abs) || !fs.statSync(abs).isFile()) {\n  throw new Error(`cover image missing: ${abs}`);\n}","typeGuard":"function isExistingFile(p: string): boolean {\n  try { return fs.existsSync(p) && fs.statSync(p).isFile(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await imagexUpload(imagePath, uploadInfo);\n} catch (e) {\n  if (String(e.message).startsWith('Cover image file not found')) {\n    console.error(`Fix path: ${e.message}`); // includes the offending path\n  }\n  throw e;\n}","preventionTips":["Resolve to absolute paths before calling upload APIs","Check fs.existsSync early in CLI argument parsing","Avoid relative paths that depend on the process cwd","Quote paths with spaces in shell commands"],"tags":["douyin","filesystem","file-not-found","upload"],"backgroundTag":"file-not-found","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}