jackwener/OpenCLI · error · CommandExecutionError

当前浏览器适配器不支持文件注入

Error message

当前浏览器适配器不支持文件注入

What it means

The draft flow injects the video file directly into the page's <input type=file> via page.setFileInput. If the current browser adapter does not implement setFileInput, a CommandExecutionError is thrown telling the user to switch to Browser Bridge or another adapter that supports file injection.

Source

Thrown at clis/douyin/draft.js:330

        if (!['.mp4', '.mov', '.avi', '.webm'].includes(ext)) {
            throw new ArgumentError(`不支持的视频格式: ${ext}(支持 mp4/mov/avi/webm)`);
        }
        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 coverPath = kwargs.cover;
        if (coverPath) {
            if (!fs.existsSync(path.resolve(coverPath))) {
                throw new ArgumentError(`封面文件不存在: ${path.resolve(coverPath)}`);
            }
        }
        if (!page.setFileInput) {
            throw new CommandExecutionError('当前浏览器适配器不支持文件注入', '请使用 Browser Bridge 或支持 setFileInput 的浏览器模式');
        }
        const visibilityLabel = VISIBILITY_LABELS[kwargs.visibility] ?? VISIBILITY_LABELS.public;
        await page.goto(DRAFT_UPLOAD_URL);
        await page.wait({ selector: 'input[type="file"]', timeout: 20 });
        await dismissKnownModals(page);
        await page.setFileInput([videoPath], 'input[type="file"]');
        await waitForDraftComposer(page);
        await dismissKnownModals(page);
        if (coverPath) {
            const coverSelector = await prepareCustomCoverInput(page);
            await page.setFileInput([path.resolve(coverPath)], coverSelector);
            await waitForCoverReady(page);
        }
        await fillDraftComposer(page, { title, caption, visibilityLabel });
        await page.wait({ time: 1 });
        const saveResult = await clickSaveDraft(page);
        const draftId = await waitForDraftResult(page, saveResult.creationId);
        return [

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Switch to the Browser Bridge adapter (or any mode supporting setFileInput) as the error message advises
  2. Upgrade the browser adapter/driver package to a version that implements setFileInput
  3. Check for the capability before running: `if (!page.setFileInput) { /* switch adapter */ }`

Example fix

// before
const page = await connect({ mode: 'cdp-attach' }); // no setFileInput
// after
const page = await connect({ mode: 'browser-bridge' }); // supports setFileInput
Defensive patterns

Strategy: fallback

Validate before calling

if (typeof page.setFileInput !== 'function') {
  console.error('Adapter lacks setFileInput — reconnect with Browser Bridge');
  process.exit(1);
}

Type guard

const supportsFileInput = (page) => typeof page?.setFileInput === 'function';

Try / catch

try {
  await cli.draft({ video, title });
} catch (e) {
  if (e instanceof CommandExecutionError && e.message.includes('不支持文件注入')) {
    const page = await connect({ mode: 'browser-bridge' });
    await cli.draft({ video, title }, { page });
  } else throw e;
}

Prevention

When it happens

Trigger: Running `douyin draft` while connected through a browser adapter lacking setFileInput — e.g. a remote/CDP-attached page object, a limited driver, or an adapter version predating the setFileInput API.

Common situations: Using a remote browser session/Bridge-less mode, older adapter versions, connecting to an already-running Chrome via plain CDP, or swapping the default browser backend in config.

Related errors


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