jackwener/OpenCLI · error · EmptyResultError
Xianyu item detail is blocked by verification or risk contro
Error message
Xianyu item detail is blocked by verification or risk control
What it means
When the in-page item-detail script returns `error: 'blocked'`, the library throws EmptyResultError('xianyu item', 'Xianyu item detail is blocked by verification or risk control'). This means goofish.com's anti-bot/risk-control layer intercepted the mtop request (CAPTCHA, slider verification, or an interstitial) rather than returning item data. It is surfaced as EMPTY_RESULT with that specific hint, not as an auth failure.
Source
Thrown at clis/xianyu/item.js:128
description: '查看闲鱼商品详情',
domain: 'www.goofish.com',
strategy: Strategy.COOKIE,
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');
}View on GitHub (pinned to 49907e53dc)
Solutions
- Slow down: add delays between item lookups and reduce request rate / concurrency.
- Open www.goofish.com in the browser profile and manually complete any CAPTCHA/slider verification shown.
- Switch to a residential IP or different network; avoid datacenter IPs.
- If you only need public info, try fetching the public item page instead of the mtop API.
Example fix
// before
for (const id of itemIds) await cli.run(['xianyu', 'item', '--item-id', id]); // triggers risk control
// after
for (const id of itemIds) {
await cli.run(['xianyu', 'item', '--item-id', id]);
await sleep(3000 + Math.random() * 2000); // throttle to avoid risk control
} Defensive patterns
Strategy: retry
Validate before calling
// Throttle before calls; back off when blocked was seen recently.
let lastBlockAt = 0;
const minIntervalMs = 5000;
async function throttle() {
const wait = lastBlockAt + minIntervalMs - Date.now();
if (wait > 0) await new Promise(r => setTimeout(r, wait));
} Type guard
function isRiskControlBlock(err) {
return err && err.code === 'EMPTY_RESULT' &&
typeof err.hint === 'string' && err.hint.includes('risk control');
} Try / catch
try {
const detail = await cli.run(['xianyu', 'item', '--item-id', itemId]);
return detail;
} catch (err) {
if (isRiskControlBlock(err)) {
await sleep(60000); // long backoff; complete any CAPTCHA in the browser profile
return null;
}
throw err;
} Prevention
- Rate-limit item lookups (seconds between calls, not milliseconds).
- Avoid datacenter IPs; use residential networks for goofish.com automation.
- Periodically check the browser profile for pending CAPTCHA/slider challenges.
- Stop and back off on the first block instead of hammering retries.
When it happens
Trigger: Running `xianyu item --item-id <id>` when the page.evaluate result has `error === 'blocked'` — the mtop call was intercepted by Xianyu verification/risk control (captcha page, slider, device fingerprint challenge).
Common situations: High request frequency / scraping many item IDs in a short window; headless browser fingerprints flagged by Alibaba risk control; datacenter IP addresses; shared account recently used from unusual locations.
Related errors
- Boss rejected the current browser environment: ${data.messag
- Xianyu blocked by verification / risk control
- item.jd.com
- SECURITY_BLOCK
- 响应不是有效 JSON
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/c245985f2bfe99b6.
Report an issue: GitHub.