jackwener/OpenCLI · error · AuthRequiredError

[taxonomy=selector_drift] site=powerchina command=search log

Error message

[taxonomy=selector_drift] site=powerchina command=search login required or human verification

What it means

An AuthRequiredError (tagged [taxonomy=selector_drift]) thrown when the powerchina search command finds zero result rows and the rendered page text contains login/captcha markers (请先登录, 未登录, 登录后, 验证码, 人机验证). The library treats 'not logged in' or 'human verification' as the reason the results were missing and surfaces it as an auth-required condition on bid.powerchina.cn, telling the caller credentials/verification are needed rather than that the query failed.

Source

Thrown at clis/powerchina/search.js:224

    }

    const rows = filterNavigationRows(
      dedupeCandidates(extractedRows).map((item) => ({
        title: cleanText(item.title),
        url: cleanText(item.url),
        date: normalizeDate(cleanText(item.date)),
        contextText: cleanText(item.contextText),
      })),
    );

    if (rows.length === 0 && extractedRows.length > 0) {
      throw new EmptyResultError('powerchina search', 'extracted only navigation/portal rows, no bid entries matched');
    }

    if (rows.length === 0) {
      const pageText = cleanText(await page.evaluate('document.body ? document.body.innerText : ""'));
      if (/(请先登录|未登录|登录后|验证码|人机验证)/.test(pageText)) {
        throw new AuthRequiredError(
          'bid.powerchina.cn',
          '[taxonomy=selector_drift] site=powerchina command=search login required or human verification',
        );
      }
      if (apiFailure) {
        throw new EmptyResultError('powerchina search', `api/dom yielded no result: ${apiFailure}`);
      }
    }

    return toProcurementSearchRecords(rows, {
      site: 'powerchina',
      query,
      limit,
    });
  },
});

export const __test__ = {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log in to bid.powerchina.cn (persist cookies/session in the browser profile used by the relay) and retry.
  2. Slow down request frequency / add delays to avoid triggering anti-bot verification.
  3. Use a different relay IP/region if the current one is captcha-gated.
  4. Solve the captcha manually once in the persistent browser profile so the session is re-established.

Example fix

// before
await cli search powerchina "招标" // fails: 未登录 page
// after
await cli login powerchina // refresh session cookies in the relay profile
await cli search powerchina "招标"
Defensive patterns

Strategy: try-catch

Validate before calling

// preflight: check for a persisted logged-in session before scraping
const pageText = await page.evaluate('document.body ? document.body.innerText : ""');
if (/(请先登录|未登录|登录后|验证码|人机验证)/.test(pageText)) {
  throw new Error('bid.powerchina.cn session expired or captcha-gated — re-authenticate first');
}

Type guard

function isAuthRequiredError(err) {
  return err instanceof AuthRequiredError || /login required or human verification/.test(String(err?.message));
}

Try / catch

try {
  rows = await searchPowerchina(query);
} catch (err) {
  if (isAuthRequiredError(err)) {
    await reloginPowerchina();      // refresh cookies in the persistent profile
    rows = await searchPowerchina(query);
  } else throw err;
}

Prevention

When it happens

Trigger: Running powerchina search where rows.length === 0 and page.evaluate('document.body.innerText') matches /(请先登录|未登录|登录后|验证码|人机验证)/ — i.e. the site rendered a login prompt or captcha page instead of results.

Common situations: Session cookie expired in the headless browser profile; site rate-limiting the relay IP into a captcha; accessing from a region/IP that forces login; scraping too aggressively triggering anti-bot human verification.

Related errors


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