jackwener/OpenCLI · error · CommandExecutionError

${checkResult.error}

Error message

${checkResult.error}

What it means

After navigating to https://www.v2ex.com/mission/daily, the command runs an in-page check script that returns {error: ...} when the page is not in the expected state. If checkResult.error is set, the command rethrows it as CommandExecutionError, optionally printing debug title/body when OPENCLI_VERBOSE is on. Typical cause: the daily-mission page didn't load as expected (not logged in, Cloudflare challenge, or V2EX markup/response changed).

Source

Thrown at clis/v2ex/daily.js:61

          if (match) {
            return { claimed: false, once: match[1], message: btn.value };
          }
        }
        
        return { 
          claimed: false, 
          error: '找到了按钮,但未能提取 once token',
          debug_title: document.title,
          debug_body: document.body.innerText.substring(0, 200).replace(/\\n/g, ' ')
        };
      }
    `);
        if (checkResult.error) {
            if (process.env.OPENCLI_VERBOSE) {
                console.error(`[opencli:v2ex:debug] Page Title: ${checkResult.debug_title}`);
                console.error(`[opencli:v2ex:debug] Page Body: ${checkResult.debug_body}`);
            }
            throw new CommandExecutionError(checkResult.error);
        }
        if (checkResult.claimed) {
            return [{ status: '✅ 已签到', message: checkResult.message }];
        }
        // Perform check in
        if (process.env.OPENCLI_VERBOSE) {
            console.error(`[opencli:v2ex] Found check-in token: once=${checkResult.once}. Checking in...`);
        }
        await page.goto(`https://www.v2ex.com/mission/daily/redeem?once=${checkResult.once}`);
        await new Promise(resolve => setTimeout(resolve, 3000)); // wait longer for redirect
        // Verify result
        const verifyResult = await page.evaluate(`
      async () => {
        const btn = document.querySelector('input.super.normal.button');
        if (!btn || !btn.value.includes('领取')) {
          // fetch balance to show user
          let balance = '';
          const balanceLink = document.querySelector('a.balance_area');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Re-run with OPENCLI_VERBOSE=1 to see the debug page title/body and identify what actually loaded.
  2. Re-authenticate the v2ex session (run the v2ex login/verify flow) so /mission/daily doesn't redirect to signin.
  3. Manually visit /mission/daily in the automation browser to clear any Cloudflare challenge, then retry.
  4. If V2EX changed the mission-page DOM, update the check script selectors in clis/v2ex/daily.js.

Example fix

// before
$ opencli v2ex daily   # CommandExecutionError: <page error>
// after
$ OPENCLI_VERBOSE=1 opencli v2ex daily   # reveals debug_title/debug_body
$ opencli v2ex login && opencli v2ex daily
Defensive patterns

Strategy: try-catch

Validate before calling

OPENCLI_VERBOSE=1 opencli v2ex daily   # inspect debug_title/debug_body before fixing
# ensure session first: cookies contain non-empty A2 for v2ex.com

Type guard

function pageCheckFailed(res) {
  return !!res && typeof res === 'object' && typeof res.error === 'string' && res.error.length > 0;
}

Try / catch

try {
  await runDaily();
} catch (e) {
  console.error('Daily check failed:', e.message);
  // re-authenticate v2ex session, clear Cloudflare, then retry once
}

Prevention

When it happens

Trigger: The page.evaluate check on /mission/daily returns an explicit error field — e.g. the mission box/ redeem button can't be found, the page is a sign-in redirect, or the DOM structure differs from what the check script expects.

Common situations: A2 session cookie expired so V2EX redirects to signin; Cloudflare interstitial not cleared within the 5-attempt bypass loop; V2EX renamed/relocated the daily-mission elements; account already redeemed in a way the script flags as an error.

Related errors


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