jackwener/OpenCLI · error · CommandExecutionError
Chess.com stats payload for ${kind}.last is not an object
Error message
Chess.com stats payload for ${kind}.last is not an object What it means
Within summarizeStats(), the k.last field (most recent rating snapshot) may be absent, but if present it must be a plain object containing e.g. rating/date. This throw fires when k.last exists but is a non-object value (string, number, array). It is a strict shape check so downstream k.last?.rating access behaves predictably.
Source
Thrown at clis/chess/utils.js:76
payload = await resp.json();
} catch (error) {
throw new CommandExecutionError(`Chess.com API returned malformed JSON for ${url}: ${error?.message || error}`);
}
if (!isPlainObject(payload)) {
throw new CommandExecutionError(`Chess.com API returned an unexpected payload shape for ${url}`);
}
return payload;
}
/** Pull rating + record fields out of a stats sub-object (`chess_rapid` etc). */
export function summarizeStats(stats, kind) {
const k = stats?.[kind];
if (!k) return null;
if (!isPlainObject(k)) {
throw new CommandExecutionError(`Chess.com stats payload for ${kind} is not an object`);
}
if (!isOptionalPlainObject(k.last)) {
throw new CommandExecutionError(`Chess.com stats payload for ${kind}.last is not an object`);
}
if (!isOptionalPlainObject(k.best)) {
throw new CommandExecutionError(`Chess.com stats payload for ${kind}.best is not an object`);
}
if (!isOptionalPlainObject(k.record)) {
throw new CommandExecutionError(`Chess.com stats payload for ${kind}.record is not an object`);
}
const record = isPlainObject(k.record) ? k.record : {};
return {
kind: kind.replace(/^chess_/, ''),
rating_current: k.last?.rating ?? '',
rating_best: k.best?.rating ?? '',
wins: record.win ?? '',
losses: record.loss ?? '',
draws: record.draw ?? '',
};
}
View on GitHub (pinned to 49907e53dc)
Solutions
- Re-fetch fresh stats from the pub API; the documented shape has last as an object with rating/date
- Inspect the offending value (typeof k.last) and fix the producer that flattened it
- If building fixtures/mocks, use last: { rating: 1500, date: 1700000000 }
- Patch the mapping layer if Chess.com altered the last field's structure
Example fix
// before
stats.chess_rapid.last = 1500; // flattened
// after
stats.chess_rapid.last = { rating: 1500, date: Math.floor(Date.now() / 1000) }; Defensive patterns
Strategy: validation
Validate before calling
const last = stats?.[kind]?.last;
if (last != null && (typeof last !== 'object' || Array.isArray(last))) {
throw new Error(`${kind}.last must be an object like { rating, date }`);
} Type guard
function hasValidLast(k) {
return k?.last == null ||
(typeof k.last === 'object' && !Array.isArray(k.last) && typeof k.last.rating === 'number');
} Try / catch
try {
const row = summarizeStats(stats, 'chess_rapid');
} catch (err) {
if (String(err.message).includes('.last is not an object')) {
console.warn('last section malformed; refetching stats');
stats = await (await fetch(`${API_BASE}/player/${user}/stats`)).json();
} else { throw err; }
} Prevention
- Keep last as { rating, date } objects; never flatten to a scalar rating
- Re-fetch from the pub API instead of trusting old normalized caches
- Validate shape when writing to cache, not only when reading
- Check typeof before reassigning nested fields in pipelines
When it happens
Trigger: Payload from /pub/player/{username}/stats where stats[kind].last is a non-object truthy value, e.g. last: "1500" or last: [..], passed via rows() or row().
Common situations: Transformed/normalized cache where last was flattened to a scalar rating; schema change on Chess.com; test fixture built with wrong nesting; a spreadsheet/CSV round-trip turned the nested object into a scalar.
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 stats payload for ${kind} is not an object
- Chess.com stats payload for ${kind}.best is not an object
- Chess.com stats payload for ${kind}.record is not an object
- Chess.com game archive entry is not an object
- Chess.com game archive entry has malformed player objects
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b2b97960b2a42421.
Report an issue: GitHub.