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

  1. Verify the game has finished and check the URL/game id is correct.
  2. Inspect pgnHeaders for White/Black/Result; if the game is in progress, wait and retry later.
  3. Fall back to alternate fields (e.g. other payload keys) if the endpoint's schema changed.
  4. 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

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


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