jackwener/OpenCLI · error · CommandExecutionError
${parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned
Error message
${parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false'} What it means
Some Xiaoyuzhou responses use a success boolean instead of (or in addition to) a numeric code. If parsed.success === false and no code-based failure was already caught, requestXoyuzhouJson throws CommandExecutionError with the API's message/msg field or a fallback string. This guards against bodies that are valid JSON with a passing code but explicitly marked unsuccessful.
Source
Thrown at clis/xiaoyuzhou/auth.js:249
throw new CommandExecutionError(`Xiaoyuzhou API returned invalid JSON: ${getErrorMessage(error)}`);
}
const serviceCode = parsed?.code;
if (serviceCode !== undefined && serviceCode !== null) {
const numericCode = Number(serviceCode);
if (!Number.isFinite(numericCode)) {
throw new CommandExecutionError('Xiaoyuzhou API returned an invalid service code');
}
if (numericCode === 401 || numericCode === 403) {
throw createXiaoyuzhouAuthError(`Xiaoyuzhou API rejected the credentials with service code ${numericCode}`);
}
if (numericCode !== 0 && numericCode !== 200) {
throw new CommandExecutionError(
parsed?.message || parsed?.msg || `Xiaoyuzhou API returned service code ${numericCode}`,
);
}
}
if (parsed?.success === false) {
throw new CommandExecutionError(parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false');
}
return {
credentials,
raw: parsed,
data: parsed?.data,
};
}
export async function fetchXiaoyuzhouTranscriptBody(url, fetchImpl = fetch) {
let response;
try {
response = await fetchImpl(url, {
method: 'GET',
headers: {
'User-Agent': XIAOYUZHOU_DEFAULT_USER_AGENT,
Accept: '*/*',
Market: 'AppStore',
},View on GitHub (pinned to 49907e53dc)
Solutions
- Read parsed.message/msg in the error output — the API explains the soft failure (e.g. permission, content unavailable).
- Verify the account has access rights to the requested content (subscription/paywall status).
- Confirm the requested resource exists and parameters (IDs, ranges) are valid.
- If this endpoint legitimately uses success:false semantics, update the CLI to branch on it explicitly instead of treating it as generic failure.
Example fix
// before: throws with fallback text only
throw new CommandExecutionError(parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false');
// after: include the raw payload for diagnosis
throw new CommandExecutionError(`${parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false'}; payload=${JSON.stringify(parsed).slice(0, 300)}`); Defensive patterns
Strategy: validation
Validate before calling
// pre-flight: confirm account access tier covers the requested resource
const account = await getXiaoyuzhouAccountInfo(creds);
if (requiresSubscription(resource) && !account.isSubscribed) {
throw new Error(`Resource ${resource.id} requires a subscription; account is free tier`);
} Type guard
function isApiSuccessEnvelope(parsed) {
return typeof parsed === 'object' && parsed !== null &&
(parsed.success === undefined || parsed.success === true);
} Try / catch
try {
const result = await requestXiaoyuzhouJson(creds, path, params);
} catch (e) {
if (e.message.includes('success=false')) {
// soft business failure: surface parsed.message to the user, don't retry blindly
console.error('API rejected request:', e.message);
} else throw e;
} Prevention
- Check subscription/permission requirements for content before requesting it.
- Verify requested IDs and parameters exist via a listing endpoint first.
- Log the full envelope on success=false — message/msg explains the soft failure.
- Treat success=false as permanent; don't retry without changing the request.
- Add tests for endpoints known to use success-based envelopes.
When it happens
Trigger: parsed.success is exactly false (strict ===) while code was absent or 0/200 — e.g. endpoints that return {success:false, message:'...'} envelopes for business-logic failures like paywalled content or incomplete data.
Common situations: Requesting premium/paywalled episode data with a free account; partial outages where the backend signals degraded success; endpoints that mix envelope styles (code-based vs success-based) and return success:false for soft failures.
Related errors
- Xiaoyuzhou API returned an invalid service code
- ${label} returned an unexpected payload shape; expected an o
- ${label} returned an unexpected payload shape; expected an a
- ${label} did not include a stable ${field}.
- archive wayback returned malformed payload: closest snapshot
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/690d79c8bf8ef6b0.
Report an issue: GitHub.