{"record":{"id":"ba73f55182ba3547","repo":"jackwener/OpenCLI","slug":"xiaoyuzhou-api-returned-an-invalid-service-code","errorCode":null,"errorMessage":"Xiaoyuzhou API returned an invalid service code","messagePattern":"Xiaoyuzhou API returned an invalid service code","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/xiaoyuzhou/auth.js","lineNumber":237,"sourceCode":"    const bodyText = await response.text();\n    if (!response.ok) {\n        if (response.status === 401 || response.status === 403) {\n            throw createXiaoyuzhouAuthError(`Xiaoyuzhou API rejected the credentials with HTTP ${response.status}`);\n        }\n        throw new CommandExecutionError(`Xiaoyuzhou API request failed with HTTP ${response.status}${bodyText ? `: ${bodyText}` : ''}`);\n    }\n    let parsed;\n    try {\n        parsed = JSON.parse(bodyText);\n    }\n    catch (error) {\n        throw new CommandExecutionError(`Xiaoyuzhou API returned invalid JSON: ${getErrorMessage(error)}`);\n    }\n    const serviceCode = parsed?.code;\n    if (serviceCode !== undefined && serviceCode !== null) {\n        const numericCode = Number(serviceCode);\n        if (!Number.isFinite(numericCode)) {\n            throw new CommandExecutionError('Xiaoyuzhou API returned an invalid service code');\n        }\n        if (numericCode === 401 || numericCode === 403) {\n            throw createXiaoyuzhouAuthError(`Xiaoyuzhou API rejected the credentials with service code ${numericCode}`);\n        }\n        if (numericCode !== 0 && numericCode !== 200) {\n            throw new CommandExecutionError(\n                parsed?.message || parsed?.msg || `Xiaoyuzhou API returned service code ${numericCode}`,\n            );\n        }\n    }\n    if (parsed?.success === false) {\n        throw new CommandExecutionError(parsed?.message || parsed?.msg || 'Xiaoyuzhou API returned success=false');\n    }\n    return {\n        credentials,\n        raw: parsed,\n        data: parsed?.data,\n    };","sourceCodeStart":219,"sourceCodeEnd":255,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/xiaoyuzhou/auth.js#L219-L255","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Print parsed?.code (JSON.stringify the whole parsed body) to inspect the unexpected schema.","Confirm the endpoint matches the currently documented Xiaoyuzhou response format (numeric code, 0/200 = success).","Update the CLI or pin an API version where the numeric code contract still holds.","If the API genuinely changed to string codes, map known string codes to numeric ones before validation."],"exampleFix":"// before\nif (!Number.isFinite(numericCode)) {\n    throw new CommandExecutionError('Xiaoyuzhou API returned an invalid service code');\n}\n// after: tolerate documented string codes\nconst STRING_CODES = { ok: 200, unauthorized: 401, forbidden: 403 };\nconst resolved = Number.isFinite(numericCode) ? numericCode : STRING_CODES[String(serviceCode).toLowerCase()];\nif (resolved === undefined) {\n    throw new CommandExecutionError(`Xiaoyuzhou API returned an invalid service code: ${JSON.stringify(serviceCode)}`);\n}","handlingStrategy":"validation","validationCode":"// call a cheap probe endpoint first and verify the envelope shape\nconst probe = JSON.parse(bodyText);\nif (!('code' in probe) || !Number.isFinite(Number(probe.code))) {\n  throw new Error(`Unexpected envelope: ${JSON.stringify(probe).slice(0, 200)}`);\n}","typeGuard":"function hasValidServiceCode(parsed) {\n  if (parsed == null || typeof parsed !== 'object') return false;\n  if (parsed.code === undefined || parsed.code === null) return true; // code optional\n  return Number.isFinite(Number(parsed.code));\n}","tryCatchPattern":"try {\n  const result = await requestXiaoyuzhouJson(creds, path, params);\n} catch (e) {\n  if (e.message === 'Xiaoyuzhou API returned an invalid service code') {\n    // dump full parsed body / check for API schema drift, update CLI mapping\n  } else throw e;\n}","preventionTips":["Pin/verify the API version so the numeric-code contract is guaranteed.","Snapshot a sample successful response in tests and assert envelope shape.","Log the full JSON body whenever the envelope fails validation.","Confirm you're pointed at the official base URL, not a mirror with a different schema."],"tags":["api-response","schema","validation"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}