Fix runRegula() hang on empty paths, WASI version stamping; release v3.2.6 - #5
Conversation
- Add RegulaError class with stdout, stderr, exitCode, and command properties - Remove console.error call (let caller handle stderr) - Treat exit code 1 as success (expected for security violations) - Update TypeScript definitions for RegulaError - Document error handling in README - Bump version to 3.2.5 Fixes: stderr from OPA errors now accessible to callers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
runRegula(paths, opts) never settled when called with an empty paths array — the promise neither resolved nor rejected. With no path arguments the regula CLI falls back to reading stdin, and execFile always hands the child an open stdin pipe, so the WASI process blocked on read indefinitely. Passing any input path was unaffected, which is why this went unnoticed. The child's stdin is now closed explicitly. Note that the two obvious fixes do not work here: execFile ignores the `stdio` option because it owns the pipes used to build the callback's stdout/stderr, and `input` is an execFileSync-only option that async execFile silently discards. Both leave the hang in place. Also stamps version.Version and version.GitCommit in build-wasi.sh, matching the Makefile. The WASI build previously reported "unknown-version, build unknown-commit" while the native binary reported real values, which was the sole failure in the WASI parity suite. Adds a regression test guarded by an explicit 30s timeout — a bare await would hang the suite rather than report a failure if this regresses. Verified it fails when the fix is reverted. Documents v3.2.5 (published to npm but never merged to master, and shipped without a changelog entry) and bumps to v3.2.6. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 16 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (11)
Comment |
CHANGELOG.md had not been updated since v3.2.1 (2023-02-16). Five releases were published to npm without ever landing here — 3.2.2, 3.2.3, 3.2.4 and 3.2.5 are all live on the registry with no entry in the file anyone actually reads. The changes/*.md files feed CHANGELOG.md via `changie merge`, which was never run for these releases (and changie is not installed in this environment), so even v3.2.4, which did have a changes/ file, was missing from the changelog. Entries for 3.2.2 and 3.2.3 are reconstructed from git history, since neither release left a changes/ file behind. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Summary
Two bugs, plus a reconciliation of master with what is actually published on npm.
runRegula()never resolves when called with an empty paths array. The promise neither resolves nor rejects:Mechanism:
index.jsinvokes the CLI viaexecFile("node", [cliPath, ...args]), which gives the child an open stdin pipe.Isolated by running the CLI directly: identical invocation exits 0 with
< /dev/nulland times out (124) with an open pipe.Impact is narrow — only the empty-paths call path. Passing input files is unaffected, so most callers never hit it. The symptom is misleading though: on the direct-CLI path the process prints its results and then hangs, so it reads as a slow evaluation rather than a stdin deadlock.
build-wasi.shdid not stamp version ldflags. The WASI build reportedunknown-version, build unknown-commitwhile the native binary reported real values — the sole failure in the WASI parity suite.On the fix
The two obvious fixes do not work, and both fail silently:
input: ""inputis anexecFileSyncoption; asyncexecFilediscards itstdio: ["ignore","pipe","pipe"]execFileoverridesstdioto own the callback's pipesVerified the second by probing: after passing
stdio: ["ignore", …],child.stdin !== nullis stilltrue. The working fix is to close the stream on the returned handle:Settles in ~1.35s, exit 0, resolving with an empty result set rather than rejecting.
Version
v3.2.5is published on npm but was never merged to master (it lived only onorigin/add-typescript-types), which is why master still read 3.2.4. This PR brings that commit along, adds the changelog entry it shipped without, and bumps to v3.2.6.Testing
awaitwould hang the suite instead of reporting a failure. Confirmed it fails when the fix is reverted (runRegula([]) did not settle within 30s).Also included
test/test-wasi.jshonoursWASI_RUNTIME(defaultnode) instead of hardcodingnode, so the parity suite can target another runtime. Without this, running the suite under a different runtime silently still shells out to node and reports a false pass.vendor/added to.gitignore— it is generated bybuild-wasi.shviago mod vendorbut was showing up as untracked.Not addressed here
Two separate issues found while investigating, deliberately left out to keep this focused:
< /dev/nullexits 0 but emitsFATAL rules/tf/aws/cloudtrail/s3_access_logging.rego:42: eval_conflict_error: object keys must be uniquewith zero bytes of stdout (reproducible 3/3). The fixed path does not hit this.node:wasicannot run any Go-compiled wasip1 module — reproduced with a three-linefmt.Printlnbinary. Bun lacksgetImportObject()andsock_accept, and past those it faults with an out-of-bounds memory access inside its ownstart(). Not fixable from this repo;cli.jsalready has a#!/usr/bin/env nodeshebang sobunx regulastill works.🤖 Generated with Claude Code