Skip to content

Conversation

@nelsondude
Copy link
Contributor

@nelsondude nelsondude commented Nov 24, 2025

Summary

Fixes RangeError when converting floating-point timestamps to BigInt in the convertToBigIntStats function.

Problem

The convertToBigIntStats() function fails when file stats contain non-integer timestamps (e.g., 1763746784088.47), throwing:

RangeError: The number 1763746784088.47 cannot be converted to a BigInt because it is not an integer

This occurs when ZIP file entries have timestamps with floating-point precision, particularly observed in Yarn 6.0.0-rc.5 when building with Storybook.

Solution

Use Math.floor() to ensure integer values before BigInt conversion on line 194 of packages/yarnpkg-fslib/sources/statUtils.ts.

Changes

  • Changed BigInt(element) to BigInt(Math.floor(element))

Testing

  • Tested with Yarn 6.0.0-rc.5 + Storybook build
  • Verified the RangeError no longer occurs with floating-point timestamps

Related

This issue was discovered while running yarn storybook build with Yarn 6.0.0-rc.5.

Fixes RangeError when file timestamps contain fractional milliseconds.
Uses Math.floor() to ensure integer conversion before BigInt.

The convertToBigIntStats function was failing when stats contained
non-integer timestamps (e.g., 1763746784088.47), throwing:
'RangeError: The number X cannot be converted to a BigInt because
it is not an integer'

This can occur when ZIP file entries have timestamps with floating-point
precision, particularly in Yarn 6.0.0-rc.5 when building with Storybook.
Copy link
Member

@arcanis arcanis left a comment

Choose a reason for hiding this comment

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

One suggestion

Comment on lines 202 to 205
bigintStats.atimeNs = bigintStats.atimeMs * BigInt(1e6);
bigintStats.mtimeNs = bigintStats.mtimeMs * BigInt(1e6);
bigintStats.ctimeNs = bigintStats.ctimeMs * BigInt(1e6);
bigintStats.birthtimeNs = bigintStats.birthtimeMs * BigInt(1e6);
Copy link
Member

Choose a reason for hiding this comment

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

These also need to be updated, as otherwise we lose the millisecond precision. Something like this should work, I think:

bigintStats.atimeNs = bigintStats.atimeMs * BigInt(1e6) + BigInt(Math.floor((stats.atimeMs % 1) * 1e3)) * BigInt(1e3);
bigintStats.mtimeNs = bigintStats.mtimeMs * BigInt(1e6) + BigInt(Math.floor((stats.mtimeMs % 1) * 1e3)) * BigInt(1e3);
bigintStats.ctimeNs = bigintStats.ctimeMs * BigInt(1e6) + BigInt(Math.floor((stats.ctimeMs % 1) * 1e3)) * BigInt(1e3);
bigintStats.birthtimeNs = bigintStats.birthtimeMs * BigInt(1e6) + BigInt(Math.floor((stats.birthtimeMs % 1) * 1e3)) * BigInt(1e3);

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated - great suggestion 👍

Address review feedback from @arcanis to preserve the fractional
part of floating-point timestamps when converting to nanoseconds.

The fractional milliseconds (e.g., 0.47ms from 1763746784088.47)
are now extracted and added as additional nanoseconds:
- 0.47ms → 470μs → 470,000ns

This ensures no precision is lost during the conversion process.
@nelsondude nelsondude requested a review from arcanis November 25, 2025 18:43
@arcanis arcanis merged commit 8452bc2 into yarnpkg:master Nov 26, 2025
26 checks passed
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