Found while porting this script to objectui (objectui#7882). The defect is in objectstack's copy, so it is filed here rather than carried silently into the port. The port already guards it; objectstack does not.
The defect
scripts/check-comment-mask-corpus.mjs, in main():
const maskerFlag = argv.indexOf('--masker');
...
const rest = argv.filter((arg, index) => index !== maskerFlag && index !== maskerFlag + 1);
const unknown = rest.filter((arg) => arg.startsWith('--'));
When --masker is ABSENT, indexOf returns -1, so maskerFlag + 1 is 0. The filter that exists to drop the flag and its value instead drops argv[0] — the first argument. That argument is removed from the very list the unknown-option check then reads.
Consequence: an unknown option in first position is not reported. The script proceeds to a full sweep and exits 0.
node scripts/check-comment-mask-corpus.mjs --no-such-flag
Expected: unknown option(s): --no-such-flag, exit 2 (EXIT_USAGE).
Actual: no usage error; the whole-tree sweep runs and the process exits 0.
Measured in the objectui port (same code path, before the guard was added): the case took 33.5 s — the sweep's wall clock — where the usage path costs milliseconds. That timing is how the port's test caught it.
Why it matters more than a typo
This is a CLI whose whole contract is its exit code, and the failure direction is the quiet one: a misspelled or renamed flag is not refused, it is ignored, and the run reports on the DEFAULT configuration while the operator believes it reported on what they asked for. A future --json, --shard or --since typed in first position would do the same. --masker in first position is unaffected, which is why the shape survives casual use.
Only the first position is affected when --masker is absent. With --masker present, maskerFlag is a real index and the filter behaves.
Suggested shape (as implemented in the objectui port)
Guard the sentinel before using it as an index, and parse the command line once, ahead of the mode dispatch, so --masker with a missing value is a usage error rather than something a later mode flag skips over:
const rest = maskerFlag === -1
? argv
: argv.filter((_arg, index) => index !== maskerFlag && index !== maskerFlag + 1);
const unknown = rest.filter((arg) => arg.startsWith('--') && arg !== '--self-test');
The objectui port covers this with cases that read parseArgs as VALUES (an unknown option is reported from argv[0] and from every other position), plus a spawned run pinning exit 2 as a number.
Not in scope of the card that found it
objectui#7882 is a measurement card about js-comment-mask.mjs's JSX residue and does not touch objectstack. Filed unassigned for triage; the objectui port carries the guard already, so nothing here is blocking it.
Found while porting this script to objectui (objectui#7882). The defect is in objectstack's copy, so it is filed here rather than carried silently into the port. The port already guards it; objectstack does not.
The defect
scripts/check-comment-mask-corpus.mjs, inmain():When
--maskeris ABSENT,indexOfreturns-1, somaskerFlag + 1is0. The filter that exists to drop the flag and its value instead dropsargv[0]— the first argument. That argument is removed from the very list the unknown-option check then reads.Consequence: an unknown option in first position is not reported. The script proceeds to a full sweep and exits 0.
Expected:
unknown option(s): --no-such-flag, exit 2 (EXIT_USAGE).Actual: no usage error; the whole-tree sweep runs and the process exits 0.
Measured in the objectui port (same code path, before the guard was added): the case took 33.5 s — the sweep's wall clock — where the usage path costs milliseconds. That timing is how the port's test caught it.
Why it matters more than a typo
This is a CLI whose whole contract is its exit code, and the failure direction is the quiet one: a misspelled or renamed flag is not refused, it is ignored, and the run reports on the DEFAULT configuration while the operator believes it reported on what they asked for. A future
--json,--shardor--sincetyped in first position would do the same.--maskerin first position is unaffected, which is why the shape survives casual use.Only the first position is affected when
--maskeris absent. With--maskerpresent,maskerFlagis a real index and the filter behaves.Suggested shape (as implemented in the objectui port)
Guard the sentinel before using it as an index, and parse the command line once, ahead of the mode dispatch, so
--maskerwith a missing value is a usage error rather than something a later mode flag skips over:The objectui port covers this with cases that read
parseArgsas VALUES (an unknown option is reported fromargv[0]and from every other position), plus a spawned run pinning exit 2 as a number.Not in scope of the card that found it
objectui#7882 is a measurement card about
js-comment-mask.mjs's JSX residue and does not touch objectstack. Filed unassigned for triage; the objectui port carries the guard already, so nothing here is blocking it.