fix: don't crash on statically-evaluated expressions that throw (BigInt mixing) - #210
Merged
Conversation
…nt mixing) The static evaluator applies JS operators directly to known values, but some of those operations can throw at evaluation time — most notably BigInt mixing: `null + 1n` throws "TypeError: Cannot mix BigInt and other types, use explicit conversions", and unary `+` on a BigInt throws "Cannot convert a BigInt value to a number". The loader evaluates the RHS of every top-level-bound assignment to track known bindings, so real-world code hits this: dd-trace 5's appsec/downstream_requests.js does `counter = null` in one function (registering null as the known binding value) and `counter = (counter + 1n) & UINT64_MAX` in another, which crashed the whole build (e.g. `ncc build` of anything depending on dd-trace 5). Wrap the operator application in BinaryExpression and UnaryExpression in try/catch — CallExpression and NewExpression already handle evaluation errors this way — so a throwing expression is simply treated as not statically computable. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Co-Authored-By: Claude <noreply@anthropic.com>
mischnic
approved these changes
Aug 6, 2026
styfle
enabled auto-merge (squash)
August 6, 2026 15:00
styfle
disabled auto-merge
August 6, 2026 15:00
6 tasks
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.
Problem
The static evaluator (
src/utils/static-eval.js) applies JS operators directly to known values, but some of those operations can throw at evaluation time:null + 1n→TypeError: Cannot mix BigInt and other types, use explicit conversions+on a BigInt:+1n→TypeError: Cannot convert a BigInt value to a numberThe loader statically evaluates the RHS of every top-level-bound assignment (to track known bindings), so real-world code hits this. dd-trace 5's
appsec/downstream_requests.jsdoes:The uncaught TypeError kills the whole compilation — e.g.
ncc buildof anything depending ondd-trace@5dies with:This blocks bumping dd-trace 4 → 5 in any ncc-bundled project (every ncc version is affected since they all bundle this loader).
Fix
Wrap the operator application in
BinaryExpressionandUnaryExpressionin try/catch, so a throwing expression is treated as not statically computable (the evaluator's existing "unknown value" semantics).CallExpressionandNewExpressionalready handle evaluation errors exactly this way, so this follows established convention in the file. The diff is best viewed with whitespace ignored.Test
Added
test/unit/static-eval-bigintreproducing the dd-trace pattern (known-nullbinding +1n, BigInt consts, and unary+on a known BigInt). Without the fix it crashes the build with the errors above; with the fix the module passes through untouched.npx jest test/index.test.js: 85/85 pass. (test/project.test.jsfails identically on unmodifiedmainin my environment — pre-existing, unrelated.)🤖 Generated with Claude Code
Related