jackwener/OpenCLI · error · CommandExecutionError

点击草稿按钮失败: ${result?.reason || 'unknown'}

Error message

点击草稿按钮失败: ${result?.reason || 'unknown'}

What it means

clickSaveDraft locates the '暂存离开' button, extracts the creation_id from the React fiber tree, and invokes the button's onClick. If the in-page script reports ok:false it throws this CommandExecutionError embedding the reason (commonly 'draft-button-missing').

Source

Thrown at clis/douyin/draft.js:262

    if (props?.onClick) {
      props.onClick({
        preventDefault() {},
        stopPropagation() {},
        nativeEvent: null,
        target: btn,
        currentTarget: btn,
      });
    } else {
      btn.click();
    }
    return {
      ok: true,
      text: (btn.textContent || '').trim(),
      creationId,
    };
  }`));
    if (!result?.ok) {
        throw new CommandExecutionError(`点击草稿按钮失败: ${result?.reason || 'unknown'}`);
    }
    if (!result.creationId) {
        throw new CommandExecutionError('点击草稿按钮失败: creation-id-missing');
    }
    return {
        text: result.text || '暂存离开',
        creationId: result.creationId,
    };
}
/**
 * Wait until creator center shows the resumable-draft prompt after saving.
 */
async function waitForDraftResult(page, creationId) {
    let lastState = { href: '', bodyText: '' };
    for (let attempt = 0; attempt < 20; attempt += 1) {
        lastState = (await page.evaluate(`() => ({
      href: location.href,
      bodyText: document.body?.innerText || ''

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Retry once — transient modals/re-renders are common and dismissKnownModals runs on the next attempt
  2. Inspect the page and update the '暂存离开' text / HTMLButtonElement selector in clis/douyin/draft.js:235-240 if Douyin changed the button
  3. Broaden the query to '[role="button"]' or span elements styled as buttons

Example fix

// before
if (!(btn instanceof HTMLButtonElement)) {
  return { ok: false, reason: 'draft-button-missing' };
}
// after: accept role=button too
if (!(btn instanceof HTMLElement)) {
  return { ok: false, reason: 'draft-button-missing' };
}
Defensive patterns

Strategy: try-catch

Try / catch

try {
  await opencli.douyin.draft({ video, title });
} catch (e) {
  if (e.message.includes('点击草稿按钮失败') && !e.message.includes('creation-id')) {
    // draft button missing — retry; ensure no modal intercepted the click
  }
}

Prevention

When it happens

Trigger: The '暂存离开' button is absent or renamed at save time — a modal covers it, the composer layout changed, or the button renders as a non-<button> element (so the HTMLButtonElement instanceof check fails).

Common situations: Douyin changed the save button copy or element type; a confirmation dialog or coach mark appeared right before saving; page re-rendered between form fill and save removing the button.

Related errors


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