jackwener/OpenCLI · error · CommandExecutionError
Chess.com callback payload is missing stable game summary fi
Error message
Chess.com callback payload is missing stable game summary fields
What it means
After extracting player names and the result from the payload/PGN headers, summarizeGame requires a non-empty whiteName, blackName, and result; this CommandExecutionError signals the callback payload lacked the stable fields needed to produce a reliable summary row.
Source
Thrown at clis/chess/game.js:47
throw new CommandExecutionError('Chess.com callback returned malformed player metadata');
}
const players = payload.players || {};
const byColor = {};
for (const slot of ['top', 'bottom']) {
const p = players[slot];
if (p !== undefined && !isPlainObject(p)) {
throw new CommandExecutionError('Chess.com callback returned malformed player metadata');
}
if (p?.color) byColor[p.color] = p;
}
const white = byColor.white || {};
const black = byColor.black || {};
const headers = g.pgnHeaders || {};
const whiteName = stringOrEmpty(white.username) || stringOrEmpty(headers.White);
const blackName = stringOrEmpty(black.username) || stringOrEmpty(headers.Black);
const result = stringOrEmpty(headers.Result);
if (!whiteName || !blackName || !result) {
throw new CommandExecutionError('Chess.com callback payload is missing stable game summary fields');
}
const headerDate = stringOrEmpty(headers.Date);
return {
kind,
game_id: id,
date: headerDate ? headerDate.replace(/\./g, '-') : formatDate(g.endTime),
white: whiteName,
white_rating: scalarOrEmpty(white.rating) || scalarOrEmpty(headers.WhiteElo),
black: blackName,
black_rating: scalarOrEmpty(black.rating) || scalarOrEmpty(headers.BlackElo),
result,
winner_color: stringOrEmpty(g.colorOfWinner),
termination: stringOrEmpty(headers.Termination) || stringOrEmpty(g.resultMessage),
eco: stringOrEmpty(headers.ECO),
time_control: stringOrEmpty(headers.TimeControl) || (typeof g.daysPerTurn === 'number' ? `${g.daysPerTurn}d/turn` : ''),
rated: g.isRated === true,
ply_count: g.plyCount ?? '',
url: `https://www.chess.com/game/${kind}/${id}`,View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the game has finished and check the URL/game id is correct.
- Inspect pgnHeaders for White/Black/Result; if the game is in progress, wait and retry later.
- Fall back to alternate fields (e.g. other payload keys) if the endpoint's schema changed.
- Re-fetch to rule out a truncated/partial cached response.
Example fix
// before
const row = summarizeGame({ kind, id, payload }); // throws if names/result missing
// after
if (!stringOrEmpty(headers.White) || !stringOrEmpty(headers.Black) || !stringOrEmpty(headers.Result)) {
// skip in-progress games instead of crashing
return null;
}
const row = summarizeGame({ kind, id, payload }); Defensive patterns
Strategy: validation
Validate before calling
const headers = payload?.game?.pgnHeaders || {};
const ok = Boolean((headers.White && headers.Black) && headers.Result);
if (!ok) console.warn('Game summary fields missing — game may be in progress'); Type guard
const hasSummaryFields = (h) => typeof h?.White === 'string' && h.White.length > 0 && typeof h?.Black === 'string' && h.Black.length > 0 && typeof h?.Result === 'string' && h.Result.length > 0;
Try / catch
try {
const row = summarizeGame({ kind, id, payload });
} catch (err) {
if (String(err.message).includes('missing stable game summary fields')) {
// treat as in-progress/unfinished game and skip or retry later
} else throw err;
} Prevention
- Only summarize finished games (filter by state/endTime when available)
- Provide fallback name sources (usernames and PGN headers) before calling
- Handle Result '*' (in-progress) explicitly
When it happens
Trigger: payload yields empty white/black names (no players.<slot>.username and no pgnHeaders.White/Black) or an empty headers.Result — e.g. games in progress, aborted games, or truncated callback responses.
Common situations: Requesting a live game that hasn't finished (Result header empty or '*'); bots/variant games missing username fields; Chess.com omitting PGN headers for certain game kinds; partially cached payloads.
Understand the failure class
Background: "Missing required field" and "field is required" errors: why libraries reject payloads that omit mandatory fields — this error's family across 20 libraries.
Related errors
- Chess.com callback returned no game payload
- Chess.com callback returned malformed PGN headers
- Chess.com callback returned malformed player metadata
- Bilibili ${label} API returned a malformed payload
- Bilibili ${label} API failed: ${message} (${payload.code})
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/5965448bb5145d7f.
Report an issue: GitHub.