{"record":{"id":"ea8f0850a1e8a757","repo":"jackwener/OpenCLI","slug":"chess-com-archives-payload-is-missing-archives-arr","errorCode":null,"errorMessage":"Chess.com archives payload is missing archives array","messagePattern":"Chess\\.com archives payload is missing archives array","errorType":"exception","errorClass":"CommandExecutionError","httpStatus":null,"severity":"error","filePath":"clis/chess/games.js","lineNumber":39,"sourceCode":"cli({\n    site: 'chess',\n    name: 'games',\n    access: 'read',\n    description: 'Chess.com recent games for a player, newest first',\n    domain: 'api.chess.com',\n    strategy: Strategy.PUBLIC,\n    browser: false,\n    args: [\n        { name: 'username', type: 'string', required: true, positional: true, help: 'Chess.com username' },\n        { name: 'limit', type: 'int', default: 10, help: `Number of recent games (1-${MAX_LIMIT})` },\n    ],\n    columns: ['date', 'time_class', 'rated', 'my_color', 'my_rating', 'my_result', 'opponent', 'opponent_rating', 'accuracy_white', 'accuracy_black', 'eco', 'opening_name', 'url'],\n    func: async (kwargs) => {\n        const username = validateUsername(kwargs.username);\n        const limit = parseLimit(kwargs.limit);\n        const archivesList = await chessApi(`/player/${encodeURIComponent(username)}/games/archives`);\n        if (!Array.isArray(archivesList.archives)) {\n            throw new CommandExecutionError('Chess.com archives payload is missing archives array');\n        }\n        const archives = archivesList.archives.slice().reverse();\n        if (archives.length === 0) {\n            throw new EmptyResultError(`Chess.com has no game archives for ${username}`);\n        }\n        const rows = [];\n        for (let i = 0; i < archives.length && i < MAX_ARCHIVE_FETCHES && rows.length < limit; i++) {\n            if (typeof archives[i] !== 'string' || !archives[i].startsWith('https://api.chess.com/pub/player/')) {\n                throw new CommandExecutionError('Chess.com archives payload contains an unexpected archive URL');\n            }\n            const monthly = await chessApi(archives[i]);\n            if (!Array.isArray(monthly.games)) {\n                throw new CommandExecutionError('Chess.com monthly archive payload is missing games array');\n            }\n            const games = monthly.games.slice().reverse();\n            for (const g of games) {\n                rows.push(mapGameRow(g, username));\n                if (rows.length >= limit) break;","sourceCodeStart":21,"sourceCodeEnd":57,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/chess/games.js#L21-L57","documentation":"After fetching /player/{username}/games/archives via chessApi, the command requires the payload to contain an archives array. If Chess.com returns something else (an error object, null, an HTML page parsed differently), the command throws CommandExecutionError instead of crashing on a missing property.","triggerScenarios":"chessApi receives a 2xx response whose body lacks .archives — e.g. the username doesn't exist but the API returns a non-404 payload, or Chess.com changed the archives response shape.","commonSituations":"Typo'd or case-sensitive mismatches in usernames; Chess.com API schema changes; proxy/captive portals returning HTML with status 200.","solutions":["Confirm the username exists by fetching https://api.chess.com/pub/player/{username} first","Check Chess.com API status/announcements for schema changes","Capture the raw payload of the archives call to see what was actually returned"],"exampleFix":"// before\nconst list = await chessApi(`/player/${username}/games/archives`);\n// after: pre-validate the player exists\nconst player = await chessApi(`/player/${encodeURIComponent(username)}`);\nif (!player || !player.username) throw new Error(`Unknown player ${username}`);\nconst list = await chessApi(`/player/${encodeURIComponent(username)}/games/archives`);","handlingStrategy":"type-guard","validationCode":"// verify the player exists before fetching archives\nconst player = await fetch(`https://api.chess.com/pub/player/${encodeURIComponent(username)}`).then(r => r.json());\nif (!player || !player.username) throw new Error(`Unknown Chess.com user: ${username}`);","typeGuard":"function hasArchives(p) { return p != null && typeof p === 'object' && Array.isArray(p.archives); }","tryCatchPattern":"try {\n  await gamesCmd(username);\n} catch (e) {\n  if (/missing archives array/.test(e.message)) {\n    // inspect raw payload / verify username / check for API schema changes\n  } else throw e;\n}","preventionTips":["Verify usernames against the /player endpoint before archive calls","Watch Chess.com API changelogs for response-shape changes","Use the published public API endpoints rather than undocumented variants"],"tags":["schema-validation","upstream-api","chess-com"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}