abhigyanpatwari/GitNexus · error · Error
Malformed --shard arg '${malformed}' — expected --shard=<ind
Error message
Malformed --shard arg '${malformed}' — expected --shard=<index>/<total> What it means
Thrown by parseShardArg() when an argv token begins with '--shard' but does not match the exact shape --shard=<digits>/<digits>. The function deliberately fails loud because a silently-dropped malformed shard flag would fall back to running the full unsharded suite (~50 spawns), re-arming the Windows watchdog timeout with no visible signal.
Source
Thrown at gitnexus/scripts/shard-arg.ts:27
*/
const SHARD_RE = /^--shard=\d+\/\d+$/;
/**
* Returns the matched `--shard=<index>/<total>` token (e.g. `--shard=1/3`) to
* pass straight through to vitest, or `undefined` when no shard arg is present.
*
* Fails loud on a shard-shaped-but-malformed arg (e.g. `--shard=1`, `--shard`,
* `--shard=abc`): a silently-ignored malformed arg would drop the shard flag and
* run the full unsharded ~50-spawn suite, re-arming the Windows watchdog timeout
* with no signal. Only `--shard` / `--shard=…` args are inspected, so unrelated
* flags (including a hypothetical `--shardx=…`) pass through untouched.
*/
export function parseShardArg(argv: string[]): string | undefined {
const shardArgs = argv.filter((a) => a === '--shard' || a.startsWith('--shard='));
const malformed = shardArgs.find((a) => !SHARD_RE.test(a));
if (malformed !== undefined) {
throw new Error(`Malformed --shard arg '${malformed}' — expected --shard=<index>/<total>`);
}
return shardArgs[0];
}
View on GitHub (pinned to d540b00184)
Solutions
- Use the exact form: --shard=<index>/<total>, e.g. --shard=1/3.
- When interpolating env vars, guard both: --shard=${INDEX}/${TOTAL} with both required and integer-validated upstream.
- Pass --shard as a single =-joined token; do not split it into two argv entries.
Example fix
# before
node scripts/run-cross-platform.js --shard "$INDEX"/"$TOTAL"
# (produces a bare '--shard' plus a separate token if INDEX is empty)
# after
node scripts/run-cross-platform.js "--shard=${INDEX}/${TOTAL}" Defensive patterns
Strategy: validation
Validate before calling
const SHARD_RE = /^--shard=(\d+)\/(\d+)$/;
function buildShardFlag(index, total) {
const i = Math.floor(Number(index));
const t = Math.floor(Number(total));
if (!Number.isInteger(i) || !Number.isInteger(t) || i < 1 || t < 1 || i > t) {
throw new Error(`cannot build shard flag from index=${index}, total=${total}`);
}
return `--shard=${i}/${t}`;
} Type guard
function isWellFormedShardArg(arg: string): boolean {
return /^--shard=\d+\/\d+$/.test(arg);
} Prevention
- Always pass --shard as a single =-joined argv token, never as two.
- When interpolating env vars, require both INDEX and TOTAL before constructing the flag.
- Add a CI step that asserts the shard flag matches /^--shard=\d+\/\d+$/ before the script runs.
When it happens
Trigger: Invoking the cross-platform script with '--shard=1' (missing /total), '--shard' alone (no value), '--shard=abc' (non-numeric), '--shard=1/' or '--shard=/3' (missing half), or '--shard=1.0/3' (float).
Common situations: A CI workflow that interpolates SHARD_INDEX and SHARD_TOTAL as separate vars but forgets one, producing '--shard=2/'; a typo passing '--shard 1/3' as two tokens (the bare '--shard' is malformed); copy-pasting vitest's '--shard=1/3' syntax but with a non-integer.
Understand the failure class
- Parsing and encoding errors: unexpected token, malformed input — why parsers reject input and how to find the real culprit.
Related errors
- shard total must be a positive integer, got ${total}
- shard index must be in 1..${total}, got ${index}
- ${flag} must be a positive integer
- ${flag} is too large
- --branch "${options.branch}" does not match the checked-out
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/a4d65e687ebfa624.
Report an issue: GitHub.