jackwener/OpenCLI · error · CommandExecutionError
Chess.com monthly archive payload is missing games array
Error message
Chess.com monthly archive payload is missing games array
What it means
Each monthly archive fetched via chessApi(archives[i]) must contain a games array. If the payload for a month lacks .games, the command throws CommandExecutionError, indicating the monthly endpoint response no longer matches the expected schema.
Source
Thrown at clis/chess/games.js:52
func: async (kwargs) => {
const username = validateUsername(kwargs.username);
const limit = parseLimit(kwargs.limit);
const archivesList = await chessApi(`/player/${encodeURIComponent(username)}/games/archives`);
if (!Array.isArray(archivesList.archives)) {
throw new CommandExecutionError('Chess.com archives payload is missing archives array');
}
const archives = archivesList.archives.slice().reverse();
if (archives.length === 0) {
throw new EmptyResultError(`Chess.com has no game archives for ${username}`);
}
const rows = [];
for (let i = 0; i < archives.length && i < MAX_ARCHIVE_FETCHES && rows.length < limit; i++) {
if (typeof archives[i] !== 'string' || !archives[i].startsWith('https://api.chess.com/pub/player/')) {
throw new CommandExecutionError('Chess.com archives payload contains an unexpected archive URL');
}
const monthly = await chessApi(archives[i]);
if (!Array.isArray(monthly.games)) {
throw new CommandExecutionError('Chess.com monthly archive payload is missing games array');
}
const games = monthly.games.slice().reverse();
for (const g of games) {
rows.push(mapGameRow(g, username));
if (rows.length >= limit) break;
}
}
if (rows.length === 0) {
throw new EmptyResultError(`Chess.com has games archives for ${username} but no games in the most recent ${MAX_ARCHIVE_FETCHES} months`);
}
return rows.slice(0, limit);
},
});
export const __test__ = { parseLimit };
View on GitHub (pinned to 49907e53dc)
Solutions
- curl the specific monthly archive URL and inspect the JSON structure
- Pin to a known-good version of this library or patch the expected field if Chess.com renamed the key
- Bypass proxies/VPN that may alter responses
Example fix
// before
const monthly = await chessApi(url);
// after
const monthly = await chessApi(url);
if (monthly && monthly.chess_games) { monthly.games = monthly.chess_games; } // adapt renamed field
if (!Array.isArray(monthly.games)) throw new CommandExecutionError('missing games array'); Defensive patterns
Strategy: type-guard
Type guard
function hasGames(p) { return p != null && typeof p === 'object' && Array.isArray(p.games); } Try / catch
try {
await gamesCmd(username);
} catch (e) {
if (/missing games array/.test(e.message)) {
// inspect the monthly payload; check Chess.com API for schema changes
} else throw e;
} Prevention
- Spot-check monthly archive JSON structure with curl during API drift concerns
- Pin library versions and read Chess.com API announcements
- Ensure no middleware returns 200 error pages for api.chess.com
When it happens
Trigger: The GET of a monthly archive URL (https://api.chess.com/pub/player/{u}/games/{yyyy}/{mm}) succeeds but the body has no games array — Chess.com schema change, an error body returned with 200, or an intermediate/proxy response.
Common situations: Chess.com API format changes; mocked API servers missing the games key; edge/CDN error pages returned with 200 status.
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
- Chess.com archives payload is missing archives array
- Chess.com archives payload contains an unexpected archive UR
- Chess.com stats payload for ${kind} is not an object
- Chess.com stats payload for ${kind}.last is not an object
- Chess.com stats payload for ${kind}.best is not an object
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a5dab49b8a5bcc8f.
Report an issue: GitHub.