jackwener/OpenCLI · error · CliError

SELECTOR

SELECTOR

Error message

Could not find element: window.lib.mtop

What it means

selectorError thrown when the in-page mtop bridge (window.lib.mtop) is not available, reported by the evaluate as error 'mtop-not-ready'. The library maps that to 'element not found' because the page's API client object never initialized.

Source

Thrown at clis/xianyu/item.js:131

    navigateBefore: false,
    browser: true,
    args: [
        { name: 'item_id', required: true, positional: true, help: '闲鱼商品 item_id' },
    ],
    columns: ['item_id', 'title', 'price', 'condition', 'brand', 'location', 'seller_name', 'want_count'],
    func: async (page, kwargs) => {
        const itemId = normalizeNumericId(kwargs.item_id, 'item_id', '1040754408976');
        await page.goto(buildItemUrl(itemId));
        await page.wait(2);
        const result = await page.evaluate(buildFetchItemEvaluate(itemId));
        if (result?.error === 'auth-required') {
            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');
        }
        if (result?.error === 'blocked') {
            throw new EmptyResultError('xianyu item', 'Xianyu item detail is blocked by verification or risk control');
        }
        if (result?.error === 'mtop-not-ready') {
            throw selectorError('window.lib.mtop', '闲鱼页面未完成初始化,无法调用商品详情接口');
        }
        if (!result || typeof result !== 'object') {
            throw new EmptyResultError('xianyu item', '闲鱼商品详情接口未返回有效数据');
        }
        const errorCode = String(result.error_code || '');
        const errorMessage = String(result.error_message || '');
        if (/FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED|FAIL_SYS/.test(errorCode) || /FAIL_SYS_SESSION_EXPIRED|SESSION_EXPIRED/.test(errorMessage)) {
            throw new AuthRequiredError('www.goofish.com', 'Xianyu item detail requires a logged-in browser session');
        }
        if (result.error) {
            throw new EmptyResultError('xianyu item', errorMessage || `Xianyu item detail request failed: ${result.error}`);
        }
        if (!String(result.title || '').trim()) {
            throw new EmptyResultError('xianyu item', 'No item detail was returned for the specified item_id');
        }
        return [result];
    },
});

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Increase the wait before evaluating so the page finishes initializing window.lib.mtop
  2. Reload the item page and retry once initialization completes
  3. Check for anti-bot interstitials that block bundle execution and solve them first
  4. If Goofish changed its internals, update the evaluate to the new mtop access path

Example fix

// before
const r = await page.evaluate(fetchItemViaMtop(id));
// after
await page.waitForFunction(() => window.lib && window.lib.mtop);
const r = await page.evaluate(fetchItemViaMtop(id));
Defensive patterns

Strategy: retry

Validate before calling

await page.waitForFunction(() => window.lib && typeof window.lib.mtop === 'object', { timeout: 15000 });

Type guard

const mtopReady = () => page.evaluate(() => Boolean(window.lib && window.lib.mtop));

Try / catch

try {
  await opencli xianyu item --id 123;
} catch (e) {
  if (e.code === 'SELECTOR' && e.message.includes('window.lib.mtop')) {
    await page.reload();
    await page.waitForFunction(() => window.lib && window.lib.mtop);
    await opencli xianyu item --id 123;
  } else throw e;
}

Prevention

When it happens

Trigger: Calling xianyu item detail (clis/xianyu/item.js) while the Goofish page has not finished booting its JS bundle, so window.lib.mtop is undefined and the mtop API call cannot be made.

Common situations: Slow network or heavy page still bootstrapping when the evaluate runs; page landed on an interstitial/version-rollback page; Goofish renamed/relocated window.lib.mtop.

Related errors


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