jackwener/OpenCLI · error · CommandExecutionError
Cover image file not found: ${imagePath}
Error message
Cover image file not found: ${imagePath} What it means
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.
Source
Thrown at clis/douyin/_shared/imagex-upload.js:36
return 'image/png';
case '.gif':
return 'image/gif';
case '.webp':
return 'image/webp';
default:
return 'image/jpeg';
}
}
/**
* Upload a cover image to ByteDance ImageX via a pre-signed PUT URL.
*
* @param imagePath - Local file path to the image (JPEG/PNG/etc.)
* @param uploadInfo - Upload URL and store_uri from the apply cover upload API
* @returns The store_uri (= image_uri for use in create_v2)
*/
export async function imagexUpload(imagePath, uploadInfo) {
if (!fs.existsSync(imagePath)) {
throw new CommandExecutionError(`Cover image file not found: ${imagePath}`, 'Ensure the file path is correct and accessible.');
}
const imageBuffer = fs.readFileSync(imagePath);
const contentType = detectContentType(imagePath);
const res = await fetch(uploadInfo.upload_url, {
method: 'PUT',
headers: {
'Content-Type': contentType,
'Content-Length': String(imageBuffer.byteLength),
},
body: imageBuffer,
});
if (!res.ok) {
const body = await res.text().catch(() => '');
throw new CommandExecutionError(`ImageX upload failed with status ${res.status}: ${body}`, 'Check that the upload URL is valid and has not expired.');
}
return uploadInfo.store_uri;
}
View on GitHub (pinned to 49907e53dc)
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.
Example fix
// before
await imagexUpload('cover.png', uploadInfo);
// after
import path from 'node:path';
import fs from 'node:fs';
const p = path.resolve('cover.png');
if (!fs.existsSync(p)) throw new Error(`cover missing: ${p}`);
await imagexUpload(p, uploadInfo); Defensive patterns
Strategy: validation
Validate before calling
import fs from 'node:fs';
import path from 'node:path';
const abs = path.resolve(imagePath);
if (!fs.existsSync(abs) || !fs.statSync(abs).isFile()) {
throw new Error(`cover image missing: ${abs}`);
} Type guard
function isExistingFile(p: string): boolean {
try { return fs.existsSync(p) && fs.statSync(p).isFile(); } catch { return false; }
} Try / catch
try {
await imagexUpload(imagePath, uploadInfo);
} catch (e) {
if (String(e.message).startsWith('Cover image file not found')) {
console.error(`Fix path: ${e.message}`); // includes the offending path
}
throw e;
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Understand the failure class
Background: "File not found" and ENOENT errors: why libraries can't find a file that should exist — this error's family across 50 libraries.
Related errors
- File not found: ${path}
- ImageX upload failed with status ${res.status}: ${body}
- TOS init multipart upload failed with status ${res.status}:
- TOS init response missing UploadId: ${res.body}
- TOS upload part ${partNumber} failed with status ${res.statu
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3f6db2b87e30c980.
Report an issue: GitHub.