jackwener/OpenCLI · error · CommandExecutionError
Chess.com callback returned malformed player metadata
Error message
Chess.com callback returned malformed player metadata
What it means
This duplicate message guards two separate checks in summarizeGame; this instance (line 29) fires when payload.players is defined but not a plain object. The CLI requires well-formed player metadata keyed by 'top'/'bottom' to build the game summary row.
Source
Thrown at clis/chess/game.js:29
function stringOrEmpty(value) {
return typeof value === 'string' ? value : '';
}
function scalarOrEmpty(value) {
return typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean' ? value : '';
}
export function summarizeGame({ kind, id, payload }) {
if (!isPlainObject(payload) || !isPlainObject(payload.game)) {
throw new CommandExecutionError('Chess.com callback returned no game payload');
}
const g = payload.game;
if (g.pgnHeaders !== undefined && !isPlainObject(g.pgnHeaders)) {
throw new CommandExecutionError('Chess.com callback returned malformed PGN headers');
}
if (payload.players !== undefined && !isPlainObject(payload.players)) {
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');View on GitHub (pinned to 49907e53dc)
Solutions
- Inspect the raw payload's players field to see its actual shape and update parsing.
- Retry the fetch in case a transient bad response caused the malformed shape.
- Check for Chess.com API changes and update the CLI or pin a compatible version.
- Validate response shape at the fetch boundary before calling summarizeGame.
Example fix
// before
const players = payload.players || {}; // crashes later if not an object
// after
if (payload.players !== undefined && !isPlainObject(payload.players)) {
throw new CommandExecutionError('Chess.com callback returned malformed player metadata');
}
const players = payload.players || {}; Defensive patterns
Strategy: type-guard
Validate before calling
if (payload?.players !== undefined && !isPlainObject(payload.players)) {
throw new Error('players is not a plain object');
} Type guard
const isPlainObject = (v) => Object.prototype.toString.call(v) === '[object Object]'; const hasValidPlayers = (p) => p.players === undefined || isPlainObject(p.players);
Try / catch
try {
const row = summarizeGame({ kind, id, payload });
} catch (err) {
if (String(err.message).includes('malformed player metadata')) {
console.error('players field shape changed; inspect raw payload');
} else throw err;
} Prevention
- Validate payload.players shape at the fetch boundary
- Keep fixtures from the real endpoint in tests
- Handle variant game types that may alter the players field
When it happens
Trigger: Chess.com callback response contains a `players` field whose value is not a plain object (array, string, null-as-present) — caught by `payload.players !== undefined && !isPlainObject(payload.players)`.
Common situations: API schema drift where players became a list; HTML/error bodies partially parsed; stale cached responses from an older endpoint version.
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.
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- Chess.com callback returned no game payload
- Chess.com callback returned malformed PGN headers
- Bilibili ${label} API returned a malformed payload
- Bilibili ${label} API returned malformed data
- Bilibili ${label} API did not return replies
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/dcab468a02a5805a.
Report an issue: GitHub.