jackwener/OpenCLI · error · AuthRequiredError
xueqiu.com
Error message
xueqiu.com
What it means
The xueqiu watchlist command calls the portfolio stock list API and expects d.data.stocks to exist. When the response is JSON but has no data.stocks field, it throws AuthRequiredError('xueqiu.com') because xueqiu typically returns an empty/error envelope ({error_code:..., error_description:...}) instead of portfolio data when the session is not authenticated to view that portfolio. The library treats a missing stocks array as an auth problem rather than an empty list.
Source
Thrown at clis/xueqiu/watchlist.js:26
description: '获取雪球自选股/模拟组合股票列表',
domain: 'xueqiu.com',
browser: true,
args: [
{
name: 'pid',
default: '-1',
help: '分组ID:-1=全部(默认) -4=模拟 -5=沪深 -6=美股 -7=港股 -10=实盘 0=持仓(通过 xueqiu groups 获取)',
},
{ name: 'limit', type: 'int', default: 100, help: '默认 100' },
],
columns: ['symbol', 'name', 'price', 'changePercent'],
func: async (page, kwargs) => {
await page.goto('https://xueqiu.com');
const pid = String(kwargs.pid || '-1');
const url = `https://stock.xueqiu.com/v5/stock/portfolio/stock/list.json?size=100&category=1&pid=${encodeURIComponent(pid)}`;
const d = await fetchXueqiuJson(page, url);
if (!d.data?.stocks)
throw new AuthRequiredError('xueqiu.com');
return (d.data.stocks || []).slice(0, kwargs.limit).map((s) => ({
symbol: s.symbol,
name: s.name,
price: s.current,
change: s.chg,
changePercent: s.percent != null ? s.percent.toFixed(2) + '%' : null,
volume: s.volume,
url: 'https://xueqiu.com/S/' + s.symbol,
}));
},
});
View on GitHub (pinned to 49907e53dc)
Solutions
- Log into xueqiu.com in the CLI browser session, then re-run the command
- Run `xueqiu groups` to list valid pid values and use one of them
- Retry with the default pid (-1) to test whether the issue is pid-specific
- Inspect the raw API response to confirm error_code/error_description
Example fix
// before
const d = await fetchXueqiuJson(page, url);
if (!d.data?.stocks) throw new AuthRequiredError('xueqiu.com');
// after (surface the API's own error message)
const d = await fetchXueqiuJson(page, url);
if (d.error_code) throw new Error(`xueqiu error ${d.error_code}: ${d.error_description}`);
if (!d.data?.stocks) throw new AuthRequiredError('xueqiu.com'); Defensive patterns
Strategy: validation
Validate before calling
const loggedIn = await page.evaluate(() => document.cookie.includes('xq_a_token'));
if (!loggedIn) throw new Error('Login to xueqiu.com before fetching watchlist'); Type guard
function hasStocks(d) { return d != null && d.data != null && Array.isArray(d.data.stocks); } Try / catch
try {
const rows = await watchlist({ pid });
} catch (e) {
if (e instanceof AuthRequiredError) {
return { error: 'AUTH_REQUIRED', hint: 'Log into xueqiu.com, or verify pid via xueqiu groups' };
}
throw e;
} Prevention
- Ensure the browser session is logged into xueqiu.com before running watchlist
- Use valid pid values obtained from `xueqiu groups` (e.g. -1, -4, -5, -6, -7, -10, 0)
- Check the API envelope's error_code field to distinguish auth issues from bad pid
- Fall back to the default pid (-1) when a specific pid returns no data
When it happens
Trigger: Calling `xueqiu watchlist` (any pid) when the response envelope lacks data.stocks — session not logged in, the pid does not exist or belongs to another user, or error_code != 0 in the response body.
Common situations: Running with an expired session where the API returns 200 with an error envelope; typo'd or invalid pid group id; private portfolio not accessible to the logged-in account.
Related errors
- 未获取到课程列表
- Chaoxing session cookies missing
- ChatGPT project requires a logged-in ChatGPT session.
- Claude sessionKey cookie missing
- Claude session incomplete — ajs_user_id cookie missing
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5615b7d543b3e1fc.
Report an issue: GitHub.