jackwener/OpenCLI · error · ArgumentError

视频文件不存在: ${videoPath}

Error message

视频文件不存在: ${videoPath}

What it means

ArgumentError thrown during the publish command's fail-fast validation when the resolved video path does not exist on disk (fs.existsSync fails after path.resolve).

Source

Thrown at clis/douyin/publish.js:115

        { name: 'schedule', required: true, help: '定时发布时间(ISO8601 或 Unix 秒,2h ~ 14天后)' },
        { name: 'caption', default: '', help: '正文内容(≤1000字,支持 #话题)' },
        { name: 'cover', default: '', help: '封面图片路径(不提供时使用视频截帧)' },
        { name: 'visibility', default: 'public', choices: ['public', 'friends', 'private'] },
        { name: 'allow_download', type: 'bool', default: false, help: '允许下载' },
        { name: 'collection', default: '', help: '合集 ID' },
        { name: 'activity', default: '', help: '活动 ID' },
        { name: 'poi_id', default: '', help: '地理位置 ID' },
        { name: 'poi_name', default: '', help: '地理位置名称' },
        { name: 'hotspot', default: '', help: '关联热点词' },
        { name: 'no_safety_check', type: 'bool', default: false, help: '跳过内容安全检测' },
        { name: 'sync_toutiao', type: 'bool', default: false, help: '同步发布到头条' },
    ],
    columns: ['status', 'aweme_id', 'url', 'publish_time'],
    func: async (page, kwargs) => {
        // ── Fail-fast validation ────────────────────────────────────────────
        const videoPath = path.resolve(kwargs.video);
        if (!fs.existsSync(videoPath)) {
            throw new ArgumentError(`视频文件不存在: ${videoPath}`);
        }
        const ext = path.extname(videoPath).toLowerCase();
        if (!['.mp4', '.mov', '.avi', '.webm'].includes(ext)) {
            throw new ArgumentError(`不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)`);
        }
        const fileSize = fs.statSync(videoPath).size;
        const title = kwargs.title;
        if (title.length > 30) {
            throw new ArgumentError('标题不能超过 30 字');
        }
        const caption = kwargs.caption || '';
        if (caption.length > 1000) {
            throw new ArgumentError('正文不能超过 1000 字');
        }
        const timingTs = toUnixSeconds(kwargs.schedule);
        validateTiming(timingTs);
        const visibilityType = VISIBILITY_MAP[kwargs.visibility] ?? 0;
        const coverPath = kwargs.cover;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass an absolute path (or path.resolve the path yourself before calling).
  2. Verify the file exists: ls the exact resolved path shown in the error message.
  3. Run the command from the directory you expect (cwd matters for relative paths).
  4. Ensure the upstream render/encode step completed before publishing.

Example fix

// before
opencli douyin publish --video ./out/final.mp4
// after
opencli douyin publish --video "$(pwd)/out/final.mp4"
Defensive patterns

Strategy: validation

Validate before calling

const videoPath = path.resolve(kwargs.video);
if (!fs.existsSync(videoPath)) {
  throw new Error(`video file not found: ${videoPath} (cwd=${process.cwd()})`);
}

Try / catch

try {
  await publish({ video: videoPath, title });
} catch (e) {
  if (String(e.message).startsWith('视频文件不存在')) {
    console.error('check the resolved path in the message; cwd may differ from expectation');
  }
  throw e;
}

Prevention

When it happens

Trigger: kwargs.video points to a missing file: wrong path, relative path resolved from an unexpected cwd, file deleted/moved before publish (clis/douyin/publish.js:115).

Common situations: Relative paths in scripts run from a different directory; typos in the filename; video not yet rendered by an upstream pipeline step; Windows/Unix path separator confusion.

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/de5124dffbf148e9. Report an issue: GitHub.