jackwener/OpenCLI · error · ArgumentError
Invalid Chess.com username "${value}" Usernames are 3-25 cha
Error message
Invalid Chess.com username "${value}" Usernames are 3-25 chars: a-z, 0-9, hyphen, underscore. What it means
An ArgumentError raised when the supplied username fails the USERNAME_RE pattern ^[a-zA-Z0-9_-]{3,25}$ (3-25 chars: letters, digits, hyphen, underscore). Chess.com usernames are constrained to this shape, so the library validates locally and fails fast before hitting the network.
Source
Thrown at clis/chess/utils.js:25
export const API_BASE = 'https://api.chess.com/pub';
export const UA = 'Mozilla/5.0 (compatible; opencli/1.0)';
const USERNAME_RE = /^[a-zA-Z0-9_-]{3,25}$/;
const GAME_URL_RE = /^https:\/\/www\.chess\.com\/game\/(live|daily)\/(\d+)/i;
export function isPlainObject(value) {
return value !== null && typeof value === 'object' && !Array.isArray(value);
}
function isOptionalPlainObject(value) {
return value === undefined || value === null || isPlainObject(value);
}
export function validateUsername(value) {
const s = String(value ?? '').trim().toLowerCase();
if (!s) throw new ArgumentError('<username> is required');
if (!USERNAME_RE.test(s)) {
throw new ArgumentError(`Invalid Chess.com username "${value}"`, 'Usernames are 3-25 chars: a-z, 0-9, hyphen, underscore.');
}
return s;
}
export function parseGameUrl(value) {
const s = String(value ?? '').trim();
if (!s) throw new ArgumentError('<game-url> is required');
const m = s.match(GAME_URL_RE);
if (!m) {
throw new ArgumentError(
`Invalid Chess.com game URL: "${value}"`,
'Expected https://www.chess.com/game/live/<id> or https://www.chess.com/game/daily/<id>.',
);
}
return { kind: m[1].toLowerCase(), id: m[2] };
}
export async function chessApi(path, fetchImpl = fetch) {View on GitHub (pinned to 49907e53dc)
Solutions
- Use the actual Chess.com username (the lowercase handle in the profile URL), 3-25 chars of a-z/0-9/_/- only.
- Trim stray quotes, whitespace, or shell escapes from the argument.
- Pre-validate in the caller with the same regex before invoking the library.
Example fix
// before
await chessStats({ username: 'Hikaru Nakamura' }); // space -> throws
// after
await chessStats({ username: 'hikaru' }); Defensive patterns
Strategy: validation
Validate before calling
const USERNAME_RE = /^[a-zA-Z0-9_-]{3,25}$/;
function isValidUsername(v) {
return typeof v === 'string' && USERNAME_RE.test(v.trim());
} Type guard
function isValidUsername(v) {
return typeof v === 'string' && /^[a-zA-Z0-9_-]{3,25}$/.test(v.trim());
} Try / catch
if (!isValidUsername(username)) {
throw new Error('Username must be 3-25 chars: a-z, 0-9, hyphen, underscore.');
}
try {
const rows = await chessStats({ username });
} catch (e) {
if (e.name === 'ArgumentError') console.error(e.message, e.hint || '');
else throw e;
} Prevention
- Copy the username from the profile URL rather than the display name.
- Pre-validate with the same regex the library uses.
- Strip quotes and shell-escaping artifacts from CLI input.
When it happens
Trigger: Passing a username shorter than 3 chars, longer than 25 chars, or containing spaces, '@', dots, non-ASCII, or URL characters to any command that routes through validateUsername.
Common situations: Pasting a display name with spaces instead of the URL-style username; passing an email address; accidentally including quotes or shell-escaping artifacts; passing a full profile URL as the username.
Related errors
- series_id must be a non-empty value
- Invalid Chess.com game URL: "${value}" Expected https://www.
- coingecko derivatives limit must be a positive integer
- limit must be a positive integer
- Search keyword cannot be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3e37a762130efbba.
Report an issue: GitHub.