jackwener/OpenCLI · error · CommandExecutionError

Xiaoyuzhou API returned an invalid service code

Error message

Xiaoyuzhou API returned an invalid service code

What it means

After parsing the JSON body, requestXiaoyuzhouJson reads the service-level code field (parsed?.code) expected by Xiaoyuzhou's response envelope. If code is present but not coercible to a finite number, the CLI cannot classify the response and throws this error rather than guessing success or failure.

Source

Thrown at clis/xiaoyuzhou/auth.js:237

    const bodyText = await response.text();
    if (!response.ok) {
        if (response.status === 401 || response.status === 403) {
            throw createXiaoyuzhouAuthError(`Xiaoyuzhou API rejected the credentials with HTTP ${response.status}`);
        }
        throw new CommandExecutionError(`Xiaoyuzhou API request failed with HTTP ${response.status}${bodyText ? `: ${bodyText}` : ''}`);
    }
    let parsed;
    try {
        parsed = JSON.parse(bodyText);
    }
    catch (error) {
        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,
    };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Print parsed?.code (JSON.stringify the whole parsed body) to inspect the unexpected schema.
  2. Confirm the endpoint matches the currently documented Xiaoyuzhou response format (numeric code, 0/200 = success).
  3. Update the CLI or pin an API version where the numeric code contract still holds.
  4. If the API genuinely changed to string codes, map known string codes to numeric ones before validation.

Example fix

// before
if (!Number.isFinite(numericCode)) {
    throw new CommandExecutionError('Xiaoyuzhou API returned an invalid service code');
}
// after: tolerate documented string codes
const STRING_CODES = { ok: 200, unauthorized: 401, forbidden: 403 };
const resolved = Number.isFinite(numericCode) ? numericCode : STRING_CODES[String(serviceCode).toLowerCase()];
if (resolved === undefined) {
    throw new CommandExecutionError(`Xiaoyuzhou API returned an invalid service code: ${JSON.stringify(serviceCode)}`);
}
Defensive patterns

Strategy: validation

Validate before calling

// call a cheap probe endpoint first and verify the envelope shape
const probe = JSON.parse(bodyText);
if (!('code' in probe) || !Number.isFinite(Number(probe.code))) {
  throw new Error(`Unexpected envelope: ${JSON.stringify(probe).slice(0, 200)}`);
}

Type guard

function hasValidServiceCode(parsed) {
  if (parsed == null || typeof parsed !== 'object') return false;
  if (parsed.code === undefined || parsed.code === null) return true; // code optional
  return Number.isFinite(Number(parsed.code));
}

Try / catch

try {
  const result = await requestXiaoyuzhouJson(creds, path, params);
} catch (e) {
  if (e.message === 'Xiaoyuzhou API returned an invalid service code') {
    // dump full parsed body / check for API schema drift, update CLI mapping
  } else throw e;
}

Prevention

When it happens

Trigger: API returns a JSON envelope whose code field is a non-numeric string (e.g. "code": "unauthorized"), null-like garbage, or an object/array — any case where Number(serviceCode) is NaN or Infinity.

Common situations: API version change where the service switched from numeric codes to string status enums; hitting a different/mirrored endpoint with a different response schema; a proxy that rewrites the body; typo'd base URL pointing to another service that also returns JSON with a non-numeric code.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/ba73f55182ba3547. Report an issue: GitHub.