Skip to content

Commit 240c059

Browse files
aspiersclaude
andcommitted
docs(scripts): correct 'no ARG_MAX' claim — argv is still execve-bounded
Copilot is right: spawnSync still calls execve and is subject to the OS argument-length limit. The runner's real wins are avoiding shell pipeline exit-code masking and shell word-splitting, not removing ARG_MAX. Reworded the comments in run-lex-codegen.js and package.json accordingly (the limit is ~2 MB on Linux, far above this few-KB list). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 9ad6b00 commit 240c059

2 files changed

Lines changed: 13 additions & 8 deletions

File tree

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"check": "npm run gen-api && npm run lint && npm run typecheck && npm run build && npm run test",
4343
"build": "rollup -c && npm run build:types",
4444
"build:types": "tsc --project tsconfig.build.json",
45-
"//permissions": "permission-set lexicons are published as-is but have no TS shape; lex gen-* cannot codegen them. scripts/run-lex-codegen.js runs a lex subcommand over all lexicons EXCEPT permission-sets (excluded by content — the same check generate-exports.js uses). It is a single Node process that spawns lex with the file list as argv and forwards lex's exit code, so a producer failure propagates without `set -o pipefail` (not portable across npm's sh) and there is no ARG_MAX limit.",
45+
"//permissions": "permission-set lexicons are published as-is but have no TS shape; lex gen-* cannot codegen them. scripts/run-lex-codegen.js runs a lex subcommand over all lexicons EXCEPT permission-sets (excluded by content — the same check generate-exports.js uses). It is a single Node process that spawns lex with the file list as argv and forwards lex's exit code, so a producer failure propagates without `set -o pipefail` (not portable across npm's sh) and shell word-splitting is avoided. (argv is still bounded by the OS execve arg limit, ~2 MB on Linux — far above this list.)",
4646
"gen-api": "node ./scripts/run-lex-codegen.js gen-api --yes ./generated && npm run gen-index",
4747
"gen-md": "node ./scripts/run-lex-codegen.js gen-md --yes ./lexicons.md",
4848
"gen-schemas-md": "node ./scripts/generate-schemas.js",

scripts/run-lex-codegen.js

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,17 @@
1111
* `scripts/generate-exports.js` uses — so the two cannot drift as files move.
1212
*
1313
* Why a Node runner rather than a shell pipeline:
14-
* - `lex … $(node …)` swallows a producer failure (command substitution discards
15-
* its exit code) and can hit ARG_MAX.
14+
* - `lex … $(node …)` swallows a producer failure: command substitution
15+
* discards the inner exit code, so lex runs on whatever (partial/empty)
16+
* output it produced and may report success.
1617
* - `node … | xargs -0 lex …` needs `set -o pipefail` to propagate a producer
1718
* failure, and `pipefail` is NOT portable across the `sh` npm runs scripts
1819
* with (rejected by the dash on GitHub's Ubuntu runners).
19-
* This runner is a single process with one authoritative exit code, passes the
20-
* file list to `lex` as argv (no shell, no ARG_MAX), and forwards lex's exit
21-
* code. No shell builtins involved.
20+
* This runner is a single process with one authoritative exit code: it forwards
21+
* lex's exit code (and fails on an empty list or a spawn error). Passing the
22+
* file list as argv also avoids shell word-splitting/quoting pitfalls. (It does
23+
* not lift the OS `execve` argument-length limit — argv is still bounded — but
24+
* that limit is ~2 MB on Linux, far above the few KB this list occupies.)
2225
*
2326
* Usage (in package.json):
2427
* node ./scripts/run-lex-codegen.js gen-api --yes ./generated
@@ -73,8 +76,10 @@ if (files.length === 0) {
7376
}
7477

7578
// `shell: false` (the default) — args are passed as argv, so there is no shell
76-
// word-splitting, no ARG_MAX limit from a command line, and lex's exit code is
77-
// ours. stdio inherited so `> file` redirection in the npm script still works.
79+
// word-splitting/quoting to get wrong, and lex's exit code is ours. (argv is
80+
// still subject to the OS `execve` arg-length limit, but that is ~2 MB on Linux
81+
// vs. the few KB this list occupies.) stdio inherited so `> file` redirection in
82+
// the npm script still works.
7883
const result = spawnSync("lex", [...lexArgs, ...files], { stdio: "inherit" });
7984
if (result.error) {
8085
process.stderr.write(

0 commit comments

Comments
 (0)