jackwener/OpenCLI · error · ArgumentError

weixin create-draft cover-image does not exist: ${absPath}

Error message

weixin create-draft cover-image does not exist: ${absPath}

What it means

After resolving and normalizing the cover image path, resolveCoverImage calls fs.statSync; if the path does not exist (or is inaccessible) it throws this ArgumentError including the absolute path that was checked.

Source

Thrown at clis/weixin/create-draft.js:41

async function evaluate(page, script) {
    return unwrapEvaluateResult(await page.evaluate(script));
}

function isRecoverableFileInputError(error) {
    const message = error instanceof Error ? error.message : String(error);
    return /unknown action|not supported|not[-\s]?allowed|notallowederror/i.test(message);
}

function resolveCoverImage(rawPath) {
    const value = String(rawPath ?? '').trim();
    if (!value) throw new ArgumentError('weixin create-draft cover-image cannot be empty');
    const absPath = path.resolve(value);
    let stat;
    try {
        stat = fs.statSync(absPath);
    } catch {
        throw new ArgumentError(`weixin create-draft cover-image does not exist: ${absPath}`);
    }
    if (!stat.isFile()) {
        throw new ArgumentError(`weixin create-draft cover-image is not a file: ${absPath}`);
    }
    const extension = path.extname(absPath).toLowerCase();
    const mimeType = IMAGE_MIME_TYPES.get(extension);
    if (!mimeType) {
        throw new ArgumentError('weixin create-draft cover-image must be JPEG, PNG, GIF, or WebP');
    }
    return { absPath, fileName: path.basename(absPath), mimeType };
}

async function navigateToEditor(page) {
    await page.goto(WEIXIN_HOME);
    await page.wait(3);
    const token = await evaluate(page, `(window.location.href.match(/token=(\\d+)/)||[])[1]`);
    if (!token) {
        throw new AuthRequiredError(WEIXIN_DOMAIN, 'Please log in to the WeChat Official Account platform and retry.');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the file exists at the printed absolute path (ls the path).
  2. Pass an absolute path to avoid working-directory surprises.
  3. Fix file permissions if access is denied.
  4. Check volume mounts if running inside a container.

Example fix

// before
coverImage: './cover.png'
// after
coverImage: '/home/me/assets/cover.png' // verified with ls
Defensive patterns

Strategy: validation

Validate before calling

const abs = path.resolve(coverImage);
if (!fs.existsSync(abs)) throw new Error(`cover image missing: ${abs}`);

Type guard

function isExistingFile(p) {
  try { return fs.statSync(path.resolve(p)).isFile(); } catch { return false; }
}

Try / catch

try {
  await createDraft({ coverImage });
} catch (err) {
  if (err instanceof ArgumentError && err.message.includes('does not exist')) {
    console.error('Check the path printed in the error');
  } else throw err;
}

Prevention

When it happens

Trigger: Passing a cover-image path that does not exist on disk, contains a typo, uses a wrong relative base for path.resolve, or points to a permission-denied location.

Common situations: Typos in the filename; running the CLI from a different working directory than assumed; image deleted/moved before the run; container missing the mounted file.

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


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9240bf07044f465b. Report an issue: GitHub.