jackwener/OpenCLI · error · CommandExecutionError
HTTP ${probe.httpStatus} from zsxq /v2/users/self
Error message
HTTP ${probe.httpStatus} from zsxq /v2/users/self What it means
When the /v2/users/self probe returns a non-auth HTTP failure (e.g. 403, 429, 5xx), verifyZsxqIdentity throws CommandExecutionError with the status code in the message. Unlike AuthRequiredError this signals a transport/HTTP-level problem reaching or processing the endpoint, not necessarily a login issue.
Source
Thrown at clis/zsxq/auth.js:37
headers: { Accept: 'application/json' },
});
if (r.status === 401 || r.status === 403) {
return { kind: 'auth', detail: 'zsxq /v2/users/self returned HTTP ' + r.status };
}
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 () => {View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect httpStatus in the message; retry after backoff for 429/5xx responses.
- Ensure the request goes through a real logged-in browser context with a normal User-Agent, not a blocked headless fingerprint.
- Test the endpoint manually in the same browser profile (fetch('/v2/users/self')) to see the raw response.
- Check zsxq service status or try later if it is a server-side (5xx) failure.
Example fix
// before
const id = await verifyZsxqIdentity(page);
// after
try {
const id = await verifyZsxqIdentity(page);
} catch (e) {
if (/HTTP 429|HTTP 5\d\d/.test(e.message)) {
await new Promise(r => setTimeout(r, 5000));
return verifyZsxqIdentity(page);
}
throw e;
} Defensive patterns
Strategy: retry
Validate before calling
const r = await page.request.get('https://api.zsxq.com/v2/users/self');
if ([403, 429].includes(r.status())) await sleep(5000); // back off before retry Type guard
const isHttpProbeError = (e) => /^HTTP \d{3} from zsxq/.test(e?.message || ''); Try / catch
try {
return await verifyZsxqIdentity(page);
} catch (e) {
if (isHttpProbeError(e) && /HTTP (429|5\d\d)/.test(e.message)) {
await sleep(5000);
return verifyZsxqIdentity(page);
}
throw e;
} Prevention
- Throttle zsxq API calls to avoid 429 rate limits.
- Run with a normal browser fingerprint/User-Agent to avoid WAF blocks.
- Monitor zsxq status during 5xx bursts instead of hammering retries.
When it happens
Trigger: The probe's HTTP request to https://api.zsxq.com/v2/users/self completes but with a status that is neither a recognized auth failure nor 200 — e.g. 403 rate-limit/WAF block, 500 server error, or a proxy intercepting the request.
Common situations: zsxq API rate limiting automated requests; CDN/WAF blocking headless browser fingerprints; network proxies returning error pages; transient zsxq server-side incidents.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- ${label} returned HTTP ${resp.status}: ${summarizeApiError(p
- HTTP ${result.httpStatus} from /api/organizations
- ${label} returned HTTP ${res.status}
- HTTP_ERROR
- HTTP_ERROR
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/4d4c3dc3fd46ea9d.
Report an issue: GitHub.