Skip to content

Conversation

Han5991
Copy link
Contributor

@Han5991 Han5991 commented Aug 6, 2025

util: fix numericSeparator for negative fractional numbers

Fixes a bug in util.inspect() where negative fractional numbers between -1 and 0 were incorrectly formatted when using the numericSeparator option.

Changes

  • Fix formatNumber function: Use original string representation to preserve negative sign for fractional numbers
  • Update test expectations: Correct scientific notation test to not expect numeric separators

Before

util.inspect([-0.12, -0.123], { numericSeparator: true })
// Output: '[ 0..12, 0..12_3 ]'  ❌

After

util.inspect([-0.12, -0.123], { numericSeparator: true })
// Output: '[ -0.12, -0.123 ]'  ✅

Root Cause

The issue was in the formatNumber function where String(Math.trunc(-0.12)) returns "0" instead of "-0", losing the negative sign. The fix uses the original string representation and properly slices integer and fractional parts while preserving the sign.

Testing
image

  • ✅ Existing regression test now passes
  • ✅ All util.inspect tests pass
  • ✅ No breaking changes to existing functionality

Closes #59376

Fix util.inspect() formatting bug where negative fractional numbers
between -1 and 0 lost their minus sign when numericSeparator was true.
Fixed formatNumber function to preserve sign by using original string
representation. Also corrected test expectations for scientific notation
to not apply numeric separators.
Fixes: nodejs#59376
@nodejs-github-bot nodejs-github-bot added needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module. labels Aug 6, 2025
Copy link
Member

@BridgeAR BridgeAR left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM
Thank you for addressing this

@BridgeAR BridgeAR added the request-ci Add this label to start a Jenkins CI on a PR. label Aug 6, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Aug 6, 2025
@nodejs-github-bot
Copy link
Collaborator

@Han5991
Copy link
Contributor Author

Han5991 commented Aug 6, 2025

@BridgeAR
The CI failures appear to be environment-specific flaky tests (only rhel8-x64 and some containers failing, while macOS, Windows, ARM, and
most Linux variants pass).

The core fix is working correctly - local testing confirms the negative fractional number formatting bug is resolved. Ready for merge when convenient.

@thoukydides
Copy link

Looking at the proposed fix, whilst it passes the specific examples in #59376, it appears to introduce a regression skipping insertion of the numeric separators for integers:

  const decimalIndex = StringPrototypeIndexOf(numberString, '.');
  if (decimalIndex === -1) {
    return fn(numberString, 'number');
  }

So, 1234 would be returned as 1234 instead of the correct 1_234.

Changing the early bail-out to something like this should work:

    return fn(addNumericSeparator(numberString));

@Han5991
Copy link
Contributor Author

Han5991 commented Aug 7, 2025

Looking at the proposed fix, whilst it passes the specific examples in #59376, it appears to introduce a regression skipping insertion of the numeric separators for integers:

  const decimalIndex = StringPrototypeIndexOf(numberString, '.');
  if (decimalIndex === -1) {
    return fn(numberString, 'number');
  }

So, 1234 would be returned as 1234 instead of the correct 1_234.

Changing the early bail-out to something like this should work:

    return fn(addNumericSeparator(numberString));

@thoukydides

Thanks for the feedback! I tested the integer formatting concern you raised, and it's actually working correctly with the current
implementation:

Integer formatting test results:

// All working as expected:
util.inspect(1234, { numericSeparator: true })     // -> 1_234 ✅
util.inspect(12345, { numericSeparator: true })    // -> 12_345 ✅
util.inspect(-1234, { numericSeparator: true })    // -> -1_234 ✅
util.inspect([1234, 12345], { numericSeparator: true }) // -> [ 1_234, 12_345 ] ✅

// Edge cases also work correctly:
util.inspect(123, { numericSeparator: true })      // -> 123 (no separator for < 4 digits) ✅
util.inspect(1234.0, { numericSeparator: true })   // -> 1_234 ✅

The current fix preserves all existing integer formatting behavior while correctly handling the original issue with negative fractional numbers. The
logic flow ensures that integers still go through addNumericSeparator() properly via the existing code path at line 1696.

So the implementation is working correctly for both the original bug (negative fractionals) and integer formatting. No additional changes needed! 😊

@thoukydides
Copy link

The current fix preserves all existing integer formatting behavior while correctly handling the original issue with negative fractional numbers. The logic flow ensures that integers still go through addNumericSeparator() properly via the existing code path at line 1696.

Sorry, yes @Han5991, you are correct that these cases get handled correctly in that earlier branch via the integer === number branch, so the decimalIndex === -1 condition should never be evaluated in cases where it is expected to be true.

However, the reason why this works isn't obvious from the code as written. It is contingent on String(number) and MathTrunc(number) having consistent behaviour, i.e. String(number) never inserting a decimal point in its output if MathTrunc(number) leaves the value unchanged (other than when using exponential notation). This works because 64-bit IEEE 754 floating-point values are used, which can represent all integers in the range ±2^53 exactly.

@Han5991
Copy link
Contributor Author

Han5991 commented Aug 7, 2025

The current fix preserves all existing integer formatting behavior while correctly handling the original issue with negative fractional numbers. The logic flow ensures that integers still go through addNumericSeparator() properly via the existing code path at line 1696.

Sorry, yes @Han5991, you are correct that these cases get handled correctly in that earlier branch via the integer === number branch, so the decimalIndex === -1 condition should never be evaluated in cases where it is expected to be true.

However, the reason why this works isn't obvious from the code as written. It is contingent on String(number) and MathTrunc(number) having consistent behaviour, i.e. String(number) never inserting a decimal point in its output if MathTrunc(number) leaves the value unchanged (other than when using exponential notation). This works because 64-bit IEEE 754 floating-point values are used, which can represent all integers in the range ±2^53 exactly.

image

@thoukydides
Changes have been applied.

Han5991 and others added 2 commits September 4, 2025 21:26
Add an English inline comment explaining that only non-integer numbers
reach this section, because integers (including exponential notation and
Infinity) are handled earlier. The comment also notes the IEEE-754
±2^53 exact-integer range and states that the branch is kept only as a
defensive fallback.
Remove unreachable decimalIndex === -1 defensive branch.

Co-authored-by: Ruben Bridgewater <[email protected]>
@Han5991 Han5991 force-pushed the fix/util-inspect-negative-fractional branch from 03b13e6 to 11ccf3f Compare September 4, 2025 12:26
@BridgeAR BridgeAR added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Sep 4, 2025
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Sep 4, 2025
@nodejs-github-bot

This comment was marked as outdated.

@nodejs-github-bot
Copy link
Collaborator

@BridgeAR BridgeAR added commit-queue Add this label to land a pull request using GitHub Actions. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. labels Sep 8, 2025
@nodejs-github-bot nodejs-github-bot added commit-queue-failed An error occurred while landing this pull request using GitHub Actions. and removed commit-queue Add this label to land a pull request using GitHub Actions. labels Sep 8, 2025
@nodejs-github-bot
Copy link
Collaborator

Commit Queue failed
- Loading data for nodejs/node/pull/59379
✔  Done loading data for nodejs/node/pull/59379
----------------------------------- PR info ------------------------------------
Title      util: fix numericSeparator with negative fractional numbers (#59379)
   ⚠  Could not retrieve the email or name of the PR author's from user's GitHub profile!
Branch     Han5991:fix/util-inspect-negative-fractional -> nodejs:main
Labels     util, author ready, needs-ci, commit-queue-squash
Commits    3
 - util: fix numericSeparator with negative fractional numbers
 - util: clarify unreachable decimalIndex === -1 branch
 - util: remove unreachable code in formatNumber
Committers 1
 - sangwook <[email protected]>
PR-URL: https://github.com/nodejs/node/pull/59379
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: James M Snell <[email protected]>
------------------------------ Generated metadata ------------------------------
PR-URL: https://github.com/nodejs/node/pull/59379
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: James M Snell <[email protected]>
--------------------------------------------------------------------------------
   ℹ  This PR was created on Wed, 06 Aug 2025 15:16:09 GMT
   ✔  Approvals: 2
   ✔  - Ruben Bridgewater (@BridgeAR) (TSC): https://github.com/nodejs/node/pull/59379#pullrequestreview-3185282674
   ✔  - James M Snell (@jasnell) (TSC): https://github.com/nodejs/node/pull/59379#pullrequestreview-3194617062
   ✘  Last GitHub CI failed
   ℹ  Last Full PR CI on 2025-09-07T19:33:25Z: https://ci.nodejs.org/job/node-test-pull-request/69118/
- Querying data for job/node-test-pull-request/69118/
   ✔  Last Jenkins CI successful
--------------------------------------------------------------------------------
   ✔  Aborted `git node land` session in /home/runner/work/node/node/.ncu
https://github.com/nodejs/node/actions/runs/17558828061

Copy link

codecov bot commented Sep 8, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.94%. Comparing base (3090def) to head (11ccf3f).
⚠️ Report is 252 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #59379      +/-   ##
==========================================
+ Coverage   89.37%   89.94%   +0.57%     
==========================================
  Files         654      667      +13     
  Lines      192601   196818    +4217     
  Branches    37427    38419     +992     
==========================================
+ Hits       172136   177034    +4898     
+ Misses      12987    12205     -782     
- Partials     7478     7579     +101     
Files with missing lines Coverage Δ
lib/internal/util/inspect.js 99.96% <100.00%> (+0.19%) ⬆️

... and 212 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@BridgeAR BridgeAR removed the commit-queue-failed An error occurred while landing this pull request using GitHub Actions. label Sep 8, 2025
@BridgeAR BridgeAR added the commit-queue Add this label to land a pull request using GitHub Actions. label Sep 8, 2025
@nodejs-github-bot nodejs-github-bot removed the commit-queue Add this label to land a pull request using GitHub Actions. label Sep 8, 2025
@nodejs-github-bot nodejs-github-bot merged commit 670d7ab into nodejs:main Sep 8, 2025
76 checks passed
@nodejs-github-bot
Copy link
Collaborator

Landed in 670d7ab

targos pushed a commit that referenced this pull request Sep 9, 2025
Fix util.inspect() formatting bug where negative fractional numbers
between -1 and 0 lost their minus sign when numericSeparator was true.
Fixed formatNumber function to preserve sign by using original string
representation. Also corrected test expectations for scientific notation
to not apply numeric separators.
Fixes: #59376

PR-URL: #59379
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: James M Snell <[email protected]>
tmeijn pushed a commit to tmeijn/dotfiles that referenced this pull request Sep 12, 2025
This MR contains the following updates:

| Package | Update | Change |
|---|---|---|
| [node](https://nodejs.org) ([source](https://github.com/nodejs/node)) | minor | `24.7.0` -> `24.8.0` |

MR created with the help of [el-capitano/tools/renovate-bot](https://gitlab.com/el-capitano/tools/renovate-bot).

**Proposed changes to behavior should be submitted there as MRs.**

---

### Release Notes

<details>
<summary>nodejs/node (node)</summary>

### [`v24.8.0`](https://github.com/nodejs/node/releases/tag/v24.8.0): 2025-09-10, Version 24.8.0 (Current), @&#8203;targos

[Compare Source](nodejs/node@v24.7.0...v24.8.0)

##### Notable Changes

##### HTTP/2 Network Inspection Support in Node.js

Node.js now supports inspection of HTTP/2 network calls in Chrome DevTools for Node.js.

##### Usage

Write a `test.js` script that makes HTTP/2 requests.

```js
const http2 = require('node:http2');

const client = http2.connect('https://nghttp2.org');

const req = client.request([
  ':path', '/',
  ':method', 'GET',
]);
```

Run it with these options:

```bash
node --inspect-wait --experimental-network-inspection test.js
```

Open `about:inspect` on Google Chrome and click on `Open dedicated DevTools for Node`.
The `Network` tab will let you track your HTTP/2 calls.

Contributed by Darshan Sen in [#&#8203;59611](nodejs/node#59611).

##### Other Notable Changes

- \[[`7a8e2c251d`](nodejs/node@7a8e2c251d)] - **(SEMVER-MINOR)** **crypto**: support Ed448 and ML-DSA context parameter in node:crypto (Filip Skokan) [#&#8203;59570](nodejs/node#59570)
- \[[`4b631be0b0`](nodejs/node@4b631be0b0)] - **(SEMVER-MINOR)** **crypto**: support Ed448 and ML-DSA context parameter in Web Cryptography (Filip Skokan) [#&#8203;59570](nodejs/node#59570)
- \[[`3e4b1e732c`](nodejs/node@3e4b1e732c)] - **(SEMVER-MINOR)** **crypto**: add KMAC Web Cryptography algorithms (Filip Skokan) [#&#8203;59647](nodejs/node#59647)
- \[[`b1d28785b2`](nodejs/node@b1d28785b2)] - **(SEMVER-MINOR)** **crypto**: add Argon2 Web Cryptography algorithms (Filip Skokan) [#&#8203;59544](nodejs/node#59544)
- \[[`430691d1af`](nodejs/node@430691d1af)] - **(SEMVER-MINOR)** **crypto**: support SLH-DSA KeyObject, sign, and verify (Filip Skokan) [#&#8203;59537](nodejs/node#59537)
- \[[`d6d05ba397`](nodejs/node@d6d05ba397)] - **(SEMVER-MINOR)** **worker**: add cpu profile APIs for worker (theanarkh) [#&#8203;59428](nodejs/node#59428)

##### Commits

- \[[`d913872369`](nodejs/node@d913872369)] - **assert**: cap input size in myersDiff to avoid Int32Array overflow (Haram Jeong) [#&#8203;59578](nodejs/node#59578)
- \[[`7bbbcf6666`](nodejs/node@7bbbcf6666)] - **benchmark**: sqlite prevent create both tables on prepare selects (Bruno Rodrigues) [#&#8203;59709](nodejs/node#59709)
- \[[`44d7b92271`](nodejs/node@44d7b92271)] - **benchmark**: calibrate config array-vs-concat (Rafael Gonzaga) [#&#8203;59587](nodejs/node#59587)
- \[[`7f347fc551`](nodejs/node@7f347fc551)] - **build**: fix getting OpenSSL version on Windows (Michaël Zasso) [#&#8203;59609](nodejs/node#59609)
- \[[`4a317150d5`](nodejs/node@4a317150d5)] - **build**: fix 'implicit-function-declaration' on OpenHarmony platform (hqzing) [#&#8203;59547](nodejs/node#59547)
- \[[`bda32af587`](nodejs/node@bda32af587)] - **build**: use `windows-2025` runner (Michaël Zasso) [#&#8203;59673](nodejs/node#59673)
- \[[`a4a8ed8f6e`](nodejs/node@a4a8ed8f6e)] - **build**: compile bundled uvwasi conditionally (Carlo Cabrera) [#&#8203;59622](nodejs/node#59622)
- \[[`d944a87761`](nodejs/node@d944a87761)] - **crypto**: refactor subtle methods to use synchronous import (Filip Skokan) [#&#8203;59771](nodejs/node#59771)
- \[[`7a8e2c251d`](nodejs/node@7a8e2c251d)] - **(SEMVER-MINOR)** **crypto**: support Ed448 and ML-DSA context parameter in node:crypto (Filip Skokan) [#&#8203;59570](nodejs/node#59570)
- \[[`4b631be0b0`](nodejs/node@4b631be0b0)] - **(SEMVER-MINOR)** **crypto**: support Ed448 and ML-DSA context parameter in Web Cryptography (Filip Skokan) [#&#8203;59570](nodejs/node#59570)
- \[[`3e4b1e732c`](nodejs/node@3e4b1e732c)] - **(SEMVER-MINOR)** **crypto**: add KMAC Web Cryptography algorithms (Filip Skokan) [#&#8203;59647](nodejs/node#59647)
- \[[`b1d28785b2`](nodejs/node@b1d28785b2)] - **(SEMVER-MINOR)** **crypto**: add Argon2 Web Cryptography algorithms (Filip Skokan) [#&#8203;59544](nodejs/node#59544)
- \[[`430691d1af`](nodejs/node@430691d1af)] - **(SEMVER-MINOR)** **crypto**: support SLH-DSA KeyObject, sign, and verify (Filip Skokan) [#&#8203;59537](nodejs/node#59537)
- \[[`0d1e53d935`](nodejs/node@0d1e53d935)] - **deps**: update uvwasi to 0.0.23 (Node.js GitHub Bot) [#&#8203;59791](nodejs/node#59791)
- \[[`68732cf426`](nodejs/node@68732cf426)] - **deps**: update histogram to 0.11.9 (Node.js GitHub Bot) [#&#8203;59689](nodejs/node#59689)
- \[[`f12c1ad961`](nodejs/node@f12c1ad961)] - **deps**: update googletest to [`eb2d85e`](nodejs/node@eb2d85e) (Node.js GitHub Bot) [#&#8203;59335](nodejs/node#59335)
- \[[`45af6966ae`](nodejs/node@45af6966ae)] - **deps**: upgrade npm to 11.6.0 (npm team) [#&#8203;59750](nodejs/node#59750)
- \[[`57617244a4`](nodejs/node@57617244a4)] - **deps**: V8: cherry-pick [`6b1b9bc`](nodejs/node@6b1b9bca2a8) (Xiao-Tao) [#&#8203;59283](nodejs/node#59283)
- \[[`2e6225a747`](nodejs/node@2e6225a747)] - **deps**: update amaro to 1.1.2 (Node.js GitHub Bot) [#&#8203;59616](nodejs/node#59616)
- \[[`1f7f6dfae6`](nodejs/node@1f7f6dfae6)] - **diagnostics\_channel**: revoke DEP0163 (René) [#&#8203;59758](nodejs/node#59758)
- \[[`8671a6cdb3`](nodejs/node@8671a6cdb3)] - **doc**: stabilize --disable-sigusr1 (Rafael Gonzaga) [#&#8203;59707](nodejs/node#59707)
- \[[`583b1b255d`](nodejs/node@583b1b255d)] - **doc**: update OpenSSL default security level to 2 (Jeetu Suthar) [#&#8203;59723](nodejs/node#59723)
- \[[`9b5eb6eb50`](nodejs/node@9b5eb6eb50)] - **doc**: fix missing links in the `errors` page (Nam Yooseong) [#&#8203;59427](nodejs/node#59427)
- \[[`e7bf712c57`](nodejs/node@e7bf712c57)] - **doc**: update "Type stripping in dependencies" section (Josh Kelley) [#&#8203;59652](nodejs/node#59652)
- \[[`96db47f91e`](nodejs/node@96db47f91e)] - **doc**: add Miles Guicent as triager (Miles Guicent) [#&#8203;59562](nodejs/node#59562)
- \[[`87f829bd0c`](nodejs/node@87f829bd0c)] - **doc**: mark `path.matchesGlob` as stable (Aviv Keller) [#&#8203;59572](nodejs/node#59572)
- \[[`062b2f705e`](nodejs/node@062b2f705e)] - **doc**: improve documentation for raw headers in HTTP/2 APIs (Tim Perry) [#&#8203;59633](nodejs/node#59633)
- \[[`6ab9306370`](nodejs/node@6ab9306370)] - **doc**: update install\_tools.bat free disk space (Stefan Stojanovic) [#&#8203;59579](nodejs/node#59579)
- \[[`c8d6b60da6`](nodejs/node@c8d6b60da6)] - **doc**: fix quic session instance typo (jakecastelli) [#&#8203;59642](nodejs/node#59642)
- \[[`61d0a2d1ba`](nodejs/node@61d0a2d1ba)] - **doc**: fix filehandle.read typo (Ruy Adorno) [#&#8203;59635](nodejs/node#59635)
- \[[`3276bfa0d0`](nodejs/node@3276bfa0d0)] - **doc**: update migration recomendations for `util.is**()` deprecations (Augustin Mauroy) [#&#8203;59269](nodejs/node#59269)
- \[[`11de6c7ebb`](nodejs/node@11de6c7ebb)] - **doc**: fix missing link to the Error documentation in the `http` page (Alexander Makarenko) [#&#8203;59080](nodejs/node#59080)
- \[[`f5b6829bba`](nodejs/node@f5b6829bba)] - **doc,crypto**: add description to the KEM and supports() methods (Filip Skokan) [#&#8203;59644](nodejs/node#59644)
- \[[`5bfdc7ee74`](nodejs/node@5bfdc7ee74)] - **doc,crypto**: cleanup unlinked and self method references webcrypto.md (Filip Skokan) [#&#8203;59608](nodejs/node#59608)
- \[[`010458d061`](nodejs/node@010458d061)] - **esm**: populate separate cache for require(esm) in imported CJS (Joyee Cheung) [#&#8203;59679](nodejs/node#59679)
- \[[`dbe6e63baf`](nodejs/node@dbe6e63baf)] - **esm**: fix missed renaming in ModuleJob.runSync (Joyee Cheung) [#&#8203;59724](nodejs/node#59724)
- \[[`8eb0d9d834`](nodejs/node@8eb0d9d834)] - **fs**: fix wrong order of file names in cpSync error message (Nicholas Paun) [#&#8203;59775](nodejs/node#59775)
- \[[`e69be5611f`](nodejs/node@e69be5611f)] - **fs**: fix dereference: false on cpSync (Nicholas Paun) [#&#8203;59681](nodejs/node#59681)
- \[[`2865d2ac20`](nodejs/node@2865d2ac20)] - **http**: unbreak keepAliveTimeoutBuffer (Robert Nagy) [#&#8203;59784](nodejs/node#59784)
- \[[`ade1175475`](nodejs/node@ade1175475)] - **http**: use cached '1.1' http version string (Robert Nagy) [#&#8203;59717](nodejs/node#59717)
- \[[`74a09482de`](nodejs/node@74a09482de)] - **inspector**: undici as shared-library should pass tests (Aras Abbasi) [#&#8203;59837](nodejs/node#59837)
- \[[`772f8f415a`](nodejs/node@772f8f415a)] - **inspector**: add http2 tracking support (Darshan Sen) [#&#8203;59611](nodejs/node#59611)
- \[[`3d225572d7`](nodejs/node@3d225572d7)] - ***Revert*** "**lib**: optimize writable stream buffer clearing" (Yoo) [#&#8203;59743](nodejs/node#59743)
- \[[`4fd213ce73`](nodejs/node@4fd213ce73)] - **lib**: fix isReadable and isWritable return type value (Gabriel Quaresma) [#&#8203;59089](nodejs/node#59089)
- \[[`39befddb87`](nodejs/node@39befddb87)] - **lib**: prefer TypedArrayPrototype primordials (Filip Skokan) [#&#8203;59766](nodejs/node#59766)
- \[[`0748160d2e`](nodejs/node@0748160d2e)] - **lib**: fix DOMException subclass support (Chengzhong Wu) [#&#8203;59680](nodejs/node#59680)
- \[[`1a93df808c`](nodejs/node@1a93df808c)] - **lib**: revert to using default derived class constructors (René) [#&#8203;59650](nodejs/node#59650)
- \[[`bb0755df37`](nodejs/node@bb0755df37)] - **meta**: bump `codecov/codecov-action` (dependabot\[bot]) [#&#8203;59726](nodejs/node#59726)
- \[[`45d148d9be`](nodejs/node@45d148d9be)] - **meta**: bump actions/download-artifact from 4.3.0 to 5.0.0 (dependabot\[bot]) [#&#8203;59729](nodejs/node#59729)
- \[[`01b66b122e`](nodejs/node@01b66b122e)] - **meta**: bump github/codeql-action from 3.29.2 to 3.30.0 (dependabot\[bot]) [#&#8203;59728](nodejs/node#59728)
- \[[`34f7ab5502`](nodejs/node@34f7ab5502)] - **meta**: bump actions/cache from 4.2.3 to 4.2.4 (dependabot\[bot]) [#&#8203;59727](nodejs/node#59727)
- \[[`5806ea02af`](nodejs/node@5806ea02af)] - **meta**: bump actions/checkout from 4.2.2 to 5.0.0 (dependabot\[bot]) [#&#8203;59725](nodejs/node#59725)
- \[[`f667215583`](nodejs/node@f667215583)] - **path**: refactor path joining logic for clarity and performance (Lee Jiho) [#&#8203;59781](nodejs/node#59781)
- \[[`0340fe92a6`](nodejs/node@0340fe92a6)] - **repl**: do not cause side effects in tab completion (Anna Henningsen) [#&#8203;59774](nodejs/node#59774)
- \[[`a414c1eb51`](nodejs/node@a414c1eb51)] - **repl**: fix REPL completion under unary expressions (Kingsword) [#&#8203;59744](nodejs/node#59744)
- \[[`c206f8dd87`](nodejs/node@c206f8dd87)] - **repl**: add isValidParentheses check before wrap input (Xuguang Mei) [#&#8203;59607](nodejs/node#59607)
- \[[`0bf9775ee2`](nodejs/node@0bf9775ee2)] - **sea**: implement sea.getAssetKeys() (Joyee Cheung) [#&#8203;59661](nodejs/node#59661)
- \[[`bf26b478d8`](nodejs/node@bf26b478d8)] - **sea**: allow using inspector command line flags with SEA (Joyee Cheung) [#&#8203;59568](nodejs/node#59568)
- \[[`92128a8fe2`](nodejs/node@92128a8fe2)] - **src**: use DictionaryTemplate for node\_url\_pattern (James M Snell) [#&#8203;59802](nodejs/node#59802)
- \[[`bcb29fb84f`](nodejs/node@bcb29fb84f)] - **src**: correctly report memory changes to V8 (Yaksh Bariya) [#&#8203;59623](nodejs/node#59623)
- \[[`44c24657d3`](nodejs/node@44c24657d3)] - **src**: fixup node\_messaging error handling (James M Snell) [#&#8203;59792](nodejs/node#59792)
- \[[`2cd6a3b7ec`](nodejs/node@2cd6a3b7ec)] - **src**: track async resources via pointers to stack-allocated handles (Anna Henningsen) [#&#8203;59704](nodejs/node#59704)
- \[[`34d752586f`](nodejs/node@34d752586f)] - **src**: fix build on NetBSD (Thomas Klausner) [#&#8203;59718](nodejs/node#59718)
- \[[`15fa779ac5`](nodejs/node@15fa779ac5)] - **src**: fix race on process exit and off thread CA loading (Chengzhong Wu) [#&#8203;59632](nodejs/node#59632)
- \[[`15cbd3966a`](nodejs/node@15cbd3966a)] - **src**: separate module.hasAsyncGraph and module.hasTopLevelAwait (Joyee Cheung) [#&#8203;59675](nodejs/node#59675)
- \[[`88d1ca8990`](nodejs/node@88d1ca8990)] - **src**: use non-deprecated Get/SetPrototype methods (Michaël Zasso) [#&#8203;59671](nodejs/node#59671)
- \[[`56ac9a2d46`](nodejs/node@56ac9a2d46)] - **src**: migrate WriteOneByte to WriteOneByteV2 (Chengzhong Wu) [#&#8203;59634](nodejs/node#59634)
- \[[`3d88aa9f2f`](nodejs/node@3d88aa9f2f)] - **src**: remove duplicate code (theanarkh) [#&#8203;59649](nodejs/node#59649)
- \[[`0718a70b2a`](nodejs/node@0718a70b2a)] - **src**: add name for more threads (theanarkh) [#&#8203;59601](nodejs/node#59601)
- \[[`0379a8b254`](nodejs/node@0379a8b254)] - **src**: remove JSONParser (Joyee Cheung) [#&#8203;59619](nodejs/node#59619)
- \[[`90d0a1b2e9`](nodejs/node@90d0a1b2e9)] - **src,sqlite**: refactor value conversion (Edy Silva) [#&#8203;59659](nodejs/node#59659)
- \[[`5e025c7ca7`](nodejs/node@5e025c7ca7)] - **stream**: replace manual function validation with validateFunction (방진혁) [#&#8203;59529](nodejs/node#59529)
- \[[`155a999bed`](nodejs/node@155a999bed)] - **test**: skip tests failing when run under root (Livia Medeiros) [#&#8203;59779](nodejs/node#59779)
- \[[`6313706c69`](nodejs/node@6313706c69)] - **test**: update WPT for urlpattern to [`cff1ac1`](nodejs/node@cff1ac1123) (Node.js GitHub Bot) [#&#8203;59602](nodejs/node#59602)
- \[[`41245ad4c7`](nodejs/node@41245ad4c7)] - **test**: skip more sea tests on Linux ppc64le (Richard Lau) [#&#8203;59755](nodejs/node#59755)
- \[[`df63d37ec4`](nodejs/node@df63d37ec4)] - **test**: fix internet/test-dns (Michaël Zasso) [#&#8203;59660](nodejs/node#59660)
- \[[`1f6c335e82`](nodejs/node@1f6c335e82)] - **test**: mark test-inspector-network-fetch as flaky again (Joyee Cheung) [#&#8203;59640](nodejs/node#59640)
- \[[`1798683df1`](nodejs/node@1798683df1)] - **test**: skip test-fs-cp\* tests that are constantly failing on Windows (Joyee Cheung) [#&#8203;59637](nodejs/node#59637)
- \[[`4c48ec09e5`](nodejs/node@4c48ec09e5)] - **test**: deflake test-http-keep-alive-empty-line (Luigi Pinca) [#&#8203;59595](nodejs/node#59595)
- \[[`dcdb259e85`](nodejs/node@dcdb259e85)] - **test\_runner**: fix todo inheritance (Moshe Atlow) [#&#8203;59721](nodejs/node#59721)
- \[[`24177973a2`](nodejs/node@24177973a2)] - **test\_runner**: set mock timer's interval undefined (hotpineapple) [#&#8203;59479](nodejs/node#59479)
- \[[`83d11f8a7a`](nodejs/node@83d11f8a7a)] - **tools**: print appropriate output when test aborted (hotpineapple) [#&#8203;59794](nodejs/node#59794)
- \[[`1eca2cc548`](nodejs/node@1eca2cc548)] - **tools**: use sparse checkout in `build-tarball.yml` (Antoine du Hamel) [#&#8203;59788](nodejs/node#59788)
- \[[`89fa1a929d`](nodejs/node@89fa1a929d)] - **tools**: remove unused actions from `build-tarball.yml` (Antoine du Hamel) [#&#8203;59787](nodejs/node#59787)
- \[[`794ca3511d`](nodejs/node@794ca3511d)] - **tools**: do not attempt to compress tgz archive (Antoine du Hamel) [#&#8203;59785](nodejs/node#59785)
- \[[`377bdb9b7e`](nodejs/node@377bdb9b7e)] - **tools**: add v8windbg target (Chengzhong Wu) [#&#8203;59767](nodejs/node#59767)
- \[[`6696d1d6c9`](nodejs/node@6696d1d6c9)] - **tools**: improve error handling in node\_mksnapshot (James M Snell) [#&#8203;59437](nodejs/node#59437)
- \[[`8dbd0f13e8`](nodejs/node@8dbd0f13e8)] - **tools**: add sccache to `test-internet` workflow (Antoine du Hamel) [#&#8203;59720](nodejs/node#59720)
- \[[`6523c2d7d9`](nodejs/node@6523c2d7d9)] - **tools**: update gyp-next to 0.20.4 (Node.js GitHub Bot) [#&#8203;59690](nodejs/node#59690)
- \[[`19d633f40c`](nodejs/node@19d633f40c)] - **tools**: add script to make reviewing backport MRs easier (Antoine du Hamel) [#&#8203;59161](nodejs/node#59161)
- \[[`15e547b3a4`](nodejs/node@15e547b3a4)] - **typings**: add typing for 'uv' (방진혁) [#&#8203;59606](nodejs/node#59606)
- \[[`ad5cfcc901`](nodejs/node@ad5cfcc901)] - **typings**: add missing properties in ConfigBinding (Lee Jiho) [#&#8203;59585](nodejs/node#59585)
- \[[`70d2d6d479`](nodejs/node@70d2d6d479)] - **url**: add err.input to ERR\_INVALID\_FILE\_URL\_PATH (Joyee Cheung) [#&#8203;59730](nodejs/node#59730)
- \[[`e476e43c17`](nodejs/node@e476e43c17)] - **util**: fix numericSeparator with negative fractional numbers (sangwook) [#&#8203;59379](nodejs/node#59379)
- \[[`b2e8f40d15`](nodejs/node@b2e8f40d15)] - **util**: remove unnecessary template strings (btea) [#&#8203;59201](nodejs/node#59201)
- \[[`6f79450ea2`](nodejs/node@6f79450ea2)] - **util**: remove outdated TODO comment (haramjeong) [#&#8203;59760](nodejs/node#59760)
- \[[`32731432ef`](nodejs/node@32731432ef)] - **util**: use getOptionValue('--no-deprecation') in deprecated() (haramjeong) [#&#8203;59760](nodejs/node#59760)
- \[[`65e4e68c90`](nodejs/node@65e4e68c90)] - **util**: hide duplicated stack frames when using util.inspect (Ruben Bridgewater) [#&#8203;59447](nodejs/node#59447)
- \[[`2086f3365f`](nodejs/node@2086f3365f)] - **vm**: sync-ify SourceTextModule linkage (Chengzhong Wu) [#&#8203;59000](nodejs/node#59000)
- \[[`c16163511d`](nodejs/node@c16163511d)] - **wasi**: fix `clean` target in `test/wasi/Makefile` (Antoine du Hamel) [#&#8203;59576](nodejs/node#59576)
- \[[`2e54411cb6`](nodejs/node@2e54411cb6)] - **worker**: optimize cpu profile implement (theanarkh) [#&#8203;59683](nodejs/node#59683)
- \[[`d6d05ba397`](nodejs/node@d6d05ba397)] - **(SEMVER-MINOR)** **worker**: add cpu profile APIs for worker (theanarkh) [#&#8203;59428](nodejs/node#59428)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever MR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this MR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box

---

This MR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MS45OS45IiwidXBkYXRlZEluVmVyIjoiNDEuOTkuOSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiUmVub3ZhdGUgQm90Il19-->
richardlau pushed a commit that referenced this pull request Sep 20, 2025
Fix util.inspect() formatting bug where negative fractional numbers
between -1 and 0 lost their minus sign when numericSeparator was true.
Fixed formatNumber function to preserve sign by using original string
representation. Also corrected test expectations for scientific notation
to not apply numeric separators.
Fixes: #59376

PR-URL: #59379
Reviewed-By: Ruben Bridgewater <[email protected]>
Reviewed-By: James M Snell <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

author ready PRs that have at least one approval, no pending requests for changes, and a CI started. commit-queue-squash Add this label to instruct the Commit Queue to squash all the PR commits into the first one. needs-ci PRs that need a full CI run. util Issues and PRs related to the built-in util module.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

util.inspect incorrectly formats negative fractional numbers with numericSeparator: true

5 participants