jackwener/OpenCLI · error · CommandExecutionError

未能验证${isDraft ? '草稿保存' : '发布'}成功,截图已保存到 /tmp/wechat-channels

Error message

未能验证${isDraft ? '草稿保存' : '发布'}成功,截图已保存到 /tmp/wechat-channels_publish_result_debug.png

What it means

After submitting publish/draft, the command checks successMarkers, finalUrl, and successMsg via submitSucceeded(). If none indicate success, it throws CommandExecutionError with a debug screenshot at /tmp/wechat-channels_publish_result_debug.png, meaning the outcome could not be verified — the publish may or may not have gone through.

Source

Thrown at clis/wechat-channels/publish.js:704

        ${DEEP_QUERY_FN}
        var all = deepQueryAll('*');
        for (var i = 0; i < all.length; i++) {
          var el = all[i];
          var text = (el.innerText || '').trim();
          if (el.children.length === 0 && text) {
            for (var j = 0; j < markers.length; j++) {
              if (text.includes(markers[j])) return text;
            }
          }
        }
        return '';
      })(${JSON.stringify(successMarkers)})
    `);

    const isSuccess = submitSucceeded({ isDraft, finalUrl, successMsg });
    if (!isSuccess) {
      await page.screenshot({ path: '/tmp/wechat-channels_publish_result_debug.png' });
      throw new CommandExecutionError(
        `未能验证${isDraft ? '草稿保存' : '发布'}成功,截图已保存到 /tmp/wechat-channels_publish_result_debug.png`,
        `url=${finalUrl || ''} message=${successMsg || ''}`,
      );
    }

    const verb = isDraft ? '草稿已保存' : '发布成功';
    const detailParts = [
      scheduleTime ? `定时: ${scheduleTime.toISOString()}` : null,
      successMsg || finalUrl,
    ].filter(Boolean);

    const result = [{
      status: `✅ ${verb}`,
      title: title || '',
      detail: detailParts.join(' · ') || finalUrl,
    }];

    // Leave the tab on the post list rather than the (now-submitted) create

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Inspect /tmp/wechat-channels_publish_result_debug.png and the url=/message= detail in the error to see the post-submit state
  2. Manually verify on the WeChat Channels site whether the video/draft actually published before retrying (avoid duplicates)
  3. Wait longer after clicking submit before evaluating success markers
  4. Add current success toast texts/URL patterns to successMarkers
  5. Check the returned detail string for server-side rejection reasons

Example fix

// before
const isSuccess = submitSucceeded({ isDraft, finalUrl, successMsg });
if (!isSuccess) { throw ... }
// after
await page.waitForNavigation({ timeout: 60000 }).catch(() => {});
const successMsg = await page.evaluate(`(function(markers){ ... })(${JSON.stringify(successMarkers)})`);
const isSuccess = submitSucceeded({ isDraft, finalUrl, successMsg });
Defensive patterns

Strategy: try-catch

Validate before calling

// verify submission state before declaring success
const state = await page.evaluate(() => ({ url: location.href, bodyText: document.body.innerText.slice(0, 2000) }));

Type guard

function looksSubmitted(s) {
  return typeof s?.url === 'string' && typeof s?.bodyText === 'string' &&
    (/发表成功|发布成功|保存成功|draft/.test(s.bodyText) || /success|published/.test(s.url));
}

Try / catch

try {
  await submitAndVerify(page, isDraft);
} catch (e) {
  if (/未能验证.*成功/.test(e.message)) {
    console.error('Publish outcome unverified — check /tmp/wechat-channels_publish_result_debug.png and confirm on the site before retrying to avoid duplicates.');
  } else throw e;
}

Prevention

When it happens

Trigger: submitSucceeded returned false: final URL unchanged, no success toast text found, page stuck on an error dialog or still on the edit page after submission.

Common situations: Submission rejected server-side (content review, missing cover); success toast appeared but with renamed text not in successMarkers; slow server left page mid-transition when markers were checked; duplicate-title rejection.

Related errors


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