jackwener/OpenCLI · error · AuthRequiredError
zsxq /v2/users/self 200 but user_id missing — incomplete ses
Error message
zsxq /v2/users/self 200 but user_id missing — incomplete session
What it means
The probe got HTTP 200 from /v2/users/self (so the session is authenticated enough to pass), but the response body contained no resolvable user_id (u.user_id and u.id both empty). verifyZsxqIdentity throws AuthRequiredError('zsxq.com', '... incomplete session') because a valid identity could not be established.
Source
Thrown at clis/zsxq/auth.js:41
}
if (!r.ok) return { kind: 'http', httpStatus: r.status };
const d = await r.json();
if (d?.succeeded === false || !d?.resp_data?.user) {
return { kind: 'auth', detail: 'zsxq /v2/users/self returned succeeded=false — anonymous' };
}
const u = d.resp_data.user;
return { ok: true, user_id: String(u.user_id || u.id || ''), name: String(u.name || u.nickname || '') };
} catch (e) {
return { kind: 'exception', detail: String(e && e.message || e) };
}
})()
`);
if (probe?.kind === 'auth') throw new AuthRequiredError('zsxq.com', probe.detail);
if (probe?.kind === 'http') throw new CommandExecutionError(`HTTP ${probe.httpStatus} from zsxq /v2/users/self`);
if (probe?.kind === 'exception') throw new CommandExecutionError(`zsxq whoami failed: ${probe.detail}`);
if (!probe?.ok) throw new CommandExecutionError(`Unexpected zsxq probe: ${JSON.stringify(probe)}`);
if (!probe.user_id) {
throw new AuthRequiredError('zsxq.com', 'zsxq /v2/users/self 200 but user_id missing — incomplete session');
}
return { user_id: probe.user_id, name: probe.name };
}
registerSiteAuthCommands({
site: 'zsxq',
domain: 'zsxq.com',
loginUrl: 'https://wx.zsxq.com/login',
columns: ['user_id', 'name'],
verify: verifyZsxqIdentity,
// No-navigation poll: probe the API from the current page so the login-page
// QR code isn't reset by a goto on every interval.
poll: async (page) => {
const loggedIn = await page.evaluate(`(async () => {
try {
const r = await fetch('https://api.zsxq.com/v2/users/self', { credentials: 'include', headers: { Accept: 'application/json' } });
if (!r.ok) return false;
const d = await r.json();View on GitHub (pinned to 49907e53dc)
Solutions
- Log out and log back in to zsxq in the browser profile to rebuild a complete session, then retry.
- Log the raw probe response body to check whether the field names changed (user_id/id, name/nickname) and update the extraction if the API schema shifted.
- Confirm the account is fully active (not suspended/restricted) by visiting zsxq.com in the same profile.
- Update the library in case a newer version already handles the changed response schema.
Example fix
// before
const u = await r.json();
const userId = String(u.user_id || u.id || '');
// after
const d = await r.json();
const u = d?.resp_data ?? d;
const userId = String(u?.user_id || u?.id || '');
if (!userId) throw new AuthRequiredError('zsxq.com', 'no user identity in response'); Defensive patterns
Strategy: validation
Validate before calling
const r = await page.request.get('https://api.zsxq.com/v2/users/self');
const d = await r.json();
const u = d?.resp_data ?? d;
if (!String(u?.user_id || u?.id || '')) throw new Error('session has no user_id — re-login required'); Type guard
const hasUserId = (d) => Boolean(String(d?.resp_data?.user_id || d?.resp_data?.id || d?.user_id || d?.id || ''));
Try / catch
try {
return await verifyZsxqIdentity(page);
} catch (e) {
if ((e.message || '').includes('incomplete session')) {
await logoutAndLoginZsxq(page);
return verifyZsxqIdentity(page);
}
throw e;
} Prevention
- Log out and back in after password changes or account security events.
- Log the raw /v2/users/self body when this occurs to detect API schema drift.
- Update the library when zsxq changes response field names.
When it happens
Trigger: zsxq /v2/users/self returns 200 but with an unexpected/partial body: e.g. resp_data missing, fields renamed by an API change, or a session valid for cookies but not for full account data (partially invalidated login).
Common situations: zsxq API schema change breaking the user_id/nickname extraction;半 logged-in states after password change; server returning an empty resp_data for restricted accounts.
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/a03ebbee9e0330d1.
Report an issue: GitHub.