Skip to content

fix: don't crash on statically-evaluated expressions that throw (BigInt mixing) - #210

Merged
styfle merged 1 commit into
mainfrom
fix/static-eval-bigint-mix
Aug 6, 2026
Merged

fix: don't crash on statically-evaluated expressions that throw (BigInt mixing)#210
styfle merged 1 commit into
mainfrom
fix/static-eval-bigint-mix

Conversation

@styfle

@styfle styfle commented Aug 6, 2026

Copy link
Copy Markdown
Member

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:

  • BigInt mixing: null + 1nTypeError: Cannot mix BigInt and other types, use explicit conversions
  • Unary + on a BigInt: +1nTypeError: Cannot convert a BigInt value to a number

The 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.js does:

let globalRequestCounter

function enable (_config) {
  globalRequestCounter = 0n
}

function disable () {
  globalRequestCounter = null   // <- registers null as the known binding value
}

function shouldSampleBody (req, outgoingUrl) {
  // evaluator computes `null + 1n` here and throws, crashing the build
  globalRequestCounter = (globalRequestCounter + 1n) & UINT64_MAX
  ...
}

The uncaught TypeError kills the whole compilation — e.g. ncc build of anything depending on dd-trace@5 dies with:

TypeError: Cannot mix BigInt and other types, use explicit conversions
    at Object.BinaryExpression (.../relocate-loader.js.cache.js:...)
    at walk (...)
    at computePureStaticValue (...)

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 BinaryExpression and UnaryExpression in try/catch, so a throwing expression is treated as not statically computable (the evaluator's existing "unknown value" semantics). CallExpression and NewExpression already 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-bigint reproducing the dd-trace pattern (known-null binding + 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.js fails identically on unmodified main in my environment — pre-existing, unrelated.)

🤖 Generated with Claude Code

Related

…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>
@styfle
styfle requested a review from Timer as a code owner August 6, 2026 13:37
@styfle
styfle requested a review from mischnic August 6, 2026 14:54
@styfle
styfle enabled auto-merge (squash) August 6, 2026 15:00
@styfle
styfle disabled auto-merge August 6, 2026 15:00
@styfle
styfle merged commit 295d101 into main Aug 6, 2026
9 checks passed
@styfle
styfle deleted the fix/static-eval-bigint-mix branch August 6, 2026 15:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants