fix(deps): repair malformed expression-js lockfile, add Dependabot config + PR guard - #46
Merged
Merged
Conversation
PR #45 ("chore(cve): Fix CVE 2026-41907") hand-edited expression-js/package-lock.json instead of regenerating it. The diff inserted a new `node_modules/http-proxy-middleware/node_modules/debug` entry but kept the old `"node_modules/http-proxy-middleware": {` line as untouched context, so on main: * the `debug` entry is never closed (978 `{` vs 977 `}`) * `node_modules/http-proxy-middleware` appears twice as a key, at lines 2620 and 2641 * the second entry's metadata says http-proxy-middleware@2.0.10 while its body is debug@4.x (`ms` dependency, `supports-color` peer meta) The file is therefore not valid JSON. Every npm/Dependabot consumer treats it as a missing lockfile: $ npm ci npm error code EUSAGE npm error The `npm ci` command can only install with an existing npm error package-lock.json or npm-shrinkwrap.json ... which is why Dependabot reports it cannot read the file and has stopped opening updates for /expression-js. Regenerated from the last valid lockfile (dda4c2c) with the webpack-dev-server ^6.0.0 bump from #45 preserved, so churn stays minimal: direct devDependencies are untouched apart from webpack-dev-server 5.2.5 -> 6.0.0. The transitive churn (express 4 -> 5, http-proxy-middleware 2 -> 4, chokidar 3 -> 5, ...) is what that major bump pulls in. Also picks up ajv 8.17.1 -> 8.20.0 (GHSA-2g4f-4pwh-qvx6) and fast-uri 3.1.2 -> 3.1.5 (GHSA-v2hh-gcrm-f6hx, GHSA-7p8r-x3mc-p8w7, GHSA-4c8g-83qw-93j6). webpack.config.js has no `devServer` block, so the dev-server major bump has no config surface to break. Verified on node 24.11.1 / npm 11.6.2: lockfile parses, root packages[""].devDependencies matches package.json exactly, every resolved direct dep satisfies its declared range, no duplicate keys anywhere in the document, `npm ci` exits 0 and `npm audit` reports 0 vulnerabilities. Not verified: `wasm-pack`. `npm run build` exits 0 but the WasmPackPlugin step fails silently -- root Cargo.lock pins wit-bindgen 0.51.0, which needs cargo >= 1.85 (edition2024), while expression-js/rust-toolchain.toml pins channel 1.81, so pkg/index.js is emitted at 1 byte. That is pre-existing on main and unrelated to this change, but it means the release publish workflow is currently shipping an empty wasm bundle. Tracking separately. Drive-by: fix the repository URL typo (ago-expression -> lago-expression). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Two reasons the broken lockfile in #45 went unnoticed for a month: 1. There is no .github/dependabot.yml in this repo at all, so there are no version-update PRs for any ecosystem here -- only org-level security updates, which silently produce nothing once a manifest stops parsing. Add entries for npm (/expression-js), cargo (/), bundler (/expression-ruby), gomod (/expression-go) and github-actions, staggered Mon-Fri so they don't all land at once. One cargo entry covers every Rust crate: expression-core, expression-js, expression-go and expression-ruby/ext/lago_expression are all members of the root workspace and resolve against the root Cargo.lock. expression-core/Cargo.lock is vestigial (31 packages vs the root's 109, still pinning lago-expression 0.1.0) -- cargo never reads it, so it gets no entry. 2. javascript.yml only runs on `release` and `workflow_dispatch`, so no PR ever installed the JS package. Add javascript-ci.yml, which on any PR touching expression-js/package.json or package-lock.json: * JSON.parse's the lockfile -- npm ci's own error is "no lockfile found", which sends people looking in the wrong place * runs `npm ci`, which also catches a lockfile out of sync with package.json (the signature of a hand-edited lockfile) * runs `npm audit --audit-level=high` as advisory only (continue-on-error): expression-js has no runtime dependencies, and a hard failure here would block the Dependabot PRs that fix advisories Confirmed the job fails on main's lockfile: parse step exit 1, `npm ci` exit 1 (EUSAGE), and it also fails on a valid-but-out-of-sync lockfile. Deliberately no build step: `wasm-pack` currently cannot build on the toolchain expression-js pins (rust-toolchain.toml channel 1.81 vs wit-bindgen 0.51.0 needing cargo >= 1.85), so a build step would land red. Note for whoever merges: the ecosystem labels (javascript, rust, ruby, go, ci) must already exist on the repo -- Dependabot only creates its own default labels and silently drops unknown ones. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…m is real in CI The wasm build has been silently broken on main since 2026-01-20 and no release has shipped since. Two independent faults: 1. expression-js/rust-toolchain.toml pinned channel 1.81, but 0ff1b8d ("misc(ruby): Bump to 4.0.1 (#24)") regenerated the root Cargo.lock and pulled wasm-bindgen 0.2.95 -> 0.2.108, which brings wit-bindgen 0.51.0. That manifest needs the edition2024 cargo feature, stabilised in 1.85: failed to parse manifest at .../wit-bindgen-0.51.0/Cargo.toml feature `edition2024` is required ... not stabilized in this version of Cargo (1.81.0) Pinned to 1.90 rather than the 1.85 floor: building wasm-bindgen-cli 0.2.108 from source needs 1.88 (icu_* and time require rustc 1.88), and a minimum-viable pin is what let 1.81 rot in the first place. Also declares the wasm32-unknown-unknown target so rustup provisions it from the repo. 2. Nothing caught it, because @wasm-tool/wasm-pack-plugin surfaces a failed wasm-pack run as a webpack error but webpack still exits 0. On main: $ npm run build # exit 0, "compiled successfully" $ ls -l pkg/ # index.js, 0 bytes $ ls -l dist/ # index.js 5,278 B, no .module.wasm $ wasm-pack pack # exit 1 -- where javascript.yml actually dies So `npm run build` is not a usable signal. The new `wasm` job asserts on the artifacts instead: a *_bg.wasm exists, is >50KB, starts with the 0061736d magic number, webpack emitted a .module.wasm, and `wasm-pack pack` succeeds. Verified both directions on this branch: with channel 1.81 the assertions exit 1 while `npm run build` still exits 0; with 1.90 the crate compiles, pkg/index_bg.wasm is 270,792 bytes of valid wasm, webpack emits the .module.wasm and `wasm-pack pack` exits 0. Good news on impact: nothing broken was published. The last npm release, lago-expression@0.2.0 (2026-01-02), predates the breakage by 18 days and contains a healthy 193,203-byte index_bg.wasm. The failure mode is a red release, not a corrupt artifact -- javascript.yml dies at `wasm-pack pack` before `wasm-pack publish` runs. But the next release would have failed, and would have looked like a mystery. Widened the workflow path filters to expression-js/**, expression-core/**, Cargo.toml and Cargo.lock, since a cargo bump is what broke it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jdenquin
approved these changes
Aug 18, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
PR #45 hand-edited
expression-js/package-lock.jsoninstead of regenerating it, leaving an unterminatedhttp-proxy-middleware/node_modules/debugentry and a duplicatehttp-proxy-middlewarekey. The file is not valid JSON, sonpm cifails with EUSAGE and Dependabot reports it cannot read the file — which is why /expression-js has had no dependency updates since 17 July.Regenerated from the last valid lockfile with #45's
webpack-dev-server^6 bump preserved, plus adependabot.yml(none existed) and a PR check that would have caught this. Full detail in the two commit messages.Verified: lockfile parses,
npm ciexits 0,npm audit0 vulnerabilities, no duplicate keys.