The runtime inspector tests were failing on Debian 13 (both x64-asan and
aarch64) due to timeout issues. The inspector activation can be slow on
ASAN builds, causing the target processes to exit before the inspector
banner is printed.
Changes:
- Increase test timeouts from 5s to 30s for the target process scripts
- Add explicit { timeout: 30_000 } option to the slow tests
This fixes the CI failures on debian-13-x64-asan and debian-13-aarch64.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
### What does this PR do?
### How did you verify your code works?
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Previously, reactFastRefresh was silently ignored when target was not
'browser', even when explicitly enabled. This was confusing as there was
no warning or error.
This change removes the `target == .browser` check, trusting explicit
user intent. If users enable reactFastRefresh with a non-browser target,
the transform will now be applied. If `$RefreshReg$` is not defined at
runtime, it will fail fast with a clear error rather than silently doing
nothing.
Use case: Terminal UIs (like [termcast](https://termcast.app)) need
React Fast Refresh with target: 'bun' for hot reloading in non-browser
environments.
### How did you verify your code works?
Updated existing test removing target browser
## Summary
- Fixes `bun init --minimal` creating Cursor rules files and CLAUDE.md
when it shouldn't
- Adds regression test to verify `--minimal` only creates package.json
and tsconfig.json
## Test plan
- [x] Verify test fails with system bun (unfixed): `USE_SYSTEM_BUN=1 bun
test test/cli/init/init.test.ts -t "bun init --minimal"`
- [x] Verify test passes with debug build: `bun bd test
test/cli/init/init.test.ts -t "bun init --minimal"`
- [x] All existing init tests pass: `bun bd test
test/cli/init/init.test.ts`
Fixes#26050🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- Add the `update` subcommand to Fish shell completions
- Apply the install/add/remove flags (--global, --dry-run, --force,
etc.) to the `update` command
Previously, Fish shell autocompletion for `bun update --gl<TAB>` would
not work because:
1. The `update` command was missing from the list of built-in commands
2. The install/add/remove flags were not being applied to `update`
Fixes#25953
## Test plan
- [x] Verify `update` appears in subcommand completions (`bun <TAB>`)
- [x] Verify `--global` flag completion works (`bun update --gl<TAB>`)
- [x] Verify other install flags work with update (--dry-run, --force,
etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Use $promiseResolveWithThen to wrap promise chains in readableStreamIntoText
and readableStreamIntoArray to ensure they return regular Promise instead of
InternalPromise.
Builtin async functions return InternalPromise by design, but this caused
`stream.text() instanceof Promise` to return false. The fix uses the existing
$promiseResolveWithThen function which 'shields' InternalPromise by wrapping
it in a regular Promise.
Claude-Generated-By: Claude Code (cli/claude-opus-4-5=100%)
Claude-Steers: 19
Claude-Permission-Prompts: 1
Claude-Escapes: 0
This updates the WebKit version to use the preview build from PR #135
which fixes async context preservation across await for AsyncLocalStorage.
Fixes the failing test: test-diagnostics-channel-tracing-channel-promise-run-stores.js
## Summary
- Add `_idleStart` property (getter/setter) to the Timeout object
returned by `setTimeout()` and `setInterval()`
- The property returns a monotonic timestamp (in milliseconds)
representing when the timer was created
- This mimics Node.js's behavior where `_idleStart` is the libuv
timestamp at timer creation time
## Test plan
- [x] Verified test fails with `USE_SYSTEM_BUN=1 bun test
test/regression/issue/25639.test.ts`
- [x] Verified test passes with `bun bd test
test/regression/issue/25639.test.ts`
- [x] Manual verification:
```bash
# Bun with fix - _idleStart exists
./build/debug/bun-debug -e "const t = setTimeout(() => {}, 0);
console.log('_idleStart' in t, typeof t._idleStart); clearTimeout(t)"
# Output: true number
# Node.js reference - same behavior
node -e "const t = setTimeout(() => {}, 0); console.log('_idleStart' in
t, typeof t._idleStart); clearTimeout(t)"
# Output: true number
```
Closes#25639🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
- Fixes handler context not being restored after minifying nested CSS
rules
- Adds regression test for the issue
## Test plan
- [x] Test fails with `USE_SYSTEM_BUN=1 bun test
test/regression/issue/25794.test.ts`
- [x] Test passes with `bun bd test test/regression/issue/25794.test.ts`
Fixes#25794🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Summary
Fix a memory leak in `RequestContext.doRenderWithBody()` where
`Strong.Impl` memory was leaked when proxying streaming responses
through Bun's HTTP server.
## Problem
When a streaming response (e.g., from a proxied fetch request) was
forwarded through Bun's server:
1. `response_body_readable_stream_ref` was initialized at line 1836
(from `lock.readable`) or line 1841 (via `Strong.init()`)
2. For `.Bytes` streams with `has_received_last_chunk=false`, a **new**
Strong reference was created at line 1902
3. The old Strong reference was **never deinit'd**, causing
`Strong.Impl` memory to leak
This leak accumulated over time with every streaming response proxied
through the server.
## Solution
Add `this.response_body_readable_stream_ref.deinit()` before creating
the new Strong reference. This is safe because:
- `stream` exists as a stack-local variable
- JSC's conservative GC tracks stack-local JSValues
- No GC can occur between consecutive synchronous Zig statements
- Therefore, `stream` won't be collected between `deinit()` and
`Strong.init()`
## Test
Added `test/js/web/fetch/server-response-stream-leak.test.ts` which:
- Creates a backend server that returns delayed streaming responses
- Creates a proxy server that forwards the streaming responses
- Makes 200 requests and checks that ReadableStream objects don't
accumulate
- Fails on system Bun v1.3.5 (202 leaked), passes with the fix
## Related
Similar to the Strong reference leak fixes in:
- #23313 (fetch memory leak)
- #25846 (fetch cyclic reference leak)
## What does this PR do?
Currently binary columns are returned as strings which means they get
corrupted when encoded in UTF8. This PR returns binary columns as
Buffers which is what user's actually expect and is also consistent with
PostgreSQL and SQLite.
### How did you verify your code works?
I added tests to verify the correct behavior. Before there were no tests
for binary columns at all.
This fixes#23991
Updates WebKit from 1d0216219a3c to d5bd162d9ab2.
Key changes:
- Promise system refactored to use new callMicrotask variadic template
- Added performPromiseThenWithContext for Bun's context passing
- Fixed PromiseReactionJob to properly handle empty vs undefined context
- Added @then property to JSInternalPromisePrototype
- Restored BunPerformMicrotaskJob and BunInvokeJobWithArguments cases
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#25862
### What does this PR do?
When a client sends pipelined data immediately after CONNECT request
headers in the same TCP segment, Bun now properly delivers this data to
the `head` parameter of the 'connect' event handler, matching Node.js
behavior.
This enables compatibility with Cap'n Proto's KJ HTTP library used by
Cloudflare's workerd runtime, which pipelines RPC data after CONNECT.
### How did you verify your code works?
<img width="694" height="612" alt="CleanShot 2026-01-09 at 15 30 22@2x"
src="https://github.com/user-attachments/assets/3ffe840e-1792-429c-8303-d98ac3e6912a"
/>
Tests
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
- Add comprehensive TypeScript type definitions for `Bun.Archive` in
`bun.d.ts`
- `ArchiveInput` and `ArchiveCompression` types
- Full JSDoc documentation with examples for all methods (`from`,
`write`, `extract`, `blob`, `bytes`, `files`)
- Add documentation page at `docs/runtime/archive.mdx`
- Quickstart examples
- Creating and extracting archives
- `files()` method with glob filtering
- Compression support
- Full API reference section
- Add Archive to docs sidebar under "Data & Storage"
- Add `files()` benchmark comparing `Bun.Archive.files()` vs node-tar
- Shows ~7x speedup for reading archive contents into memory (59µs vs
434µs)
## Test plan
- [x] TypeScript types compile correctly
- [x] Documentation renders properly in Mintlify format
- [x] Benchmark runs successfully and shows performance comparison
- [x] Verified `files()` method works correctly with both Bun.Archive
and node-tar
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
- Fixes a path traversal vulnerability via symlink when installing
GitHub packages
- Validates symlink targets before creation to ensure they stay within
the extraction directory
- Rejects absolute symlinks and relative paths that would escape the
extraction directory
## Details
When extracting GitHub tarballs, Bun did not validate symlink targets. A
malicious tarball could:
1. Create a symlink pointing outside the extraction directory (e.g.,
`../../../../../../../tmp`)
2. Include a file entry through that symlink path (e.g.,
`symlink-to-tmp/pwned.txt`)
When extracted, the symlink would be created first, then the file would
be written through it, ending up outside the intended package directory
(e.g., `/tmp/pwned.txt`).
### The Fix
Added `isSymlinkTargetSafe()` function that:
1. Rejects absolute symlink targets (starting with `/`)
2. Normalizes the combined path (symlink location + target) and rejects
if the result starts with `..` (would escape)
## Test plan
- [x] Added regression test
`test/cli/install/symlink-path-traversal.test.ts`
- [x] Tests verify relative path traversal symlinks are blocked
- [x] Tests verify absolute symlink targets are blocked
- [x] Tests verify safe relative symlinks within the package still work
- [x] Verified test fails with system bun (vulnerable) and passes with
debug build (fixed)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
## Summary
Adds a new CLI flag `--compile-executable-path` that allows specifying a
custom Bun executable path for cross-compilation instead of downloading
from the npm registry.
## Usage
```bash
bun build --compile --target=bun-linux-x64 \
--compile-executable-path=/path/to/bun-linux-x64 app.ts
```
## Motivation
The `executablePath` option was already available in the JavaScript
`Bun.build()` API. This exposes the same functionality from the CLI.
## Changes
- Added `--compile-executable-path <STR>` CLI parameter in
`src/cli/Arguments.zig`
- Added `compile_executable_path` field to `BundlerOptions` in
`src/cli.zig`
- Wired the option through to `StandaloneModuleGraph.toExecutable()` in
`src/cli/build_command.zig`
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
remove agent in global WebSocket (in node.js it uses dispatcher not
agent) add agent support in ws module (this actually uses agent)
### How did you verify your code works?
Tests
### What does this PR do?
Update FFI documentation with a note on Windows API handle values, as
pointer encoding to double causes intermittent failures with some
classes of handles.
Putting it in this accordion feels less than ideal but it's also a very
specific use case.
The specific issue I experienced: HDCs and HBITMAPs are basically 32
bits, although they are typedef'd in the headers to HANDLE. They are
returned from and passed to the GDI APIs as sign-extended versions of
the underlying 32-bit value, and so when going through the ptr <->
double pathway of bun FFI, the bottom 11 bits of those values are lost
if the original value had bit 31 set, and subsequent calls will fail.
Probably this is fixable by correctly encoding 'negative' pointers in
the double representation, and I might tackle that if I find time.
## Summary
Fixes#25869
Two fixes to enable `jest.useFakeTimers()` to work with
`@testing-library/react` and `@testing-library/user-event`:
- Set `setTimeout.clock = true` when fake timers are enabled.
testing-library/react's `jestFakeTimersAreEnabled()` checks for this
property to determine if `jest.advanceTimersByTime()` should be called
when draining the microtask queue. Without this, testing-library never
advances timers.
- Make `advanceTimersByTime(0)` fire `setTimeout(fn, 0)` timers.
`setTimeout(fn, 0)` is internally scheduled with a 1ms delay per HTML
spec. Jest/testing-library expect `advanceTimersByTime(0)` to fire such
"immediate" timers, but we were advancing by 0ms so they never fired.
## Test plan
- [x] All 30 existing fake timer tests pass
- [x] New regression test validates both fixes
- [x] Original user-event reproduction now works (test completes instead
of hanging)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
## Summary
- **libarchive.zig:110**: Fix self-assignment bug where `this.pos` was
assigned to itself instead of `new_pos`
- **s3/credentials.zig:165,176,199**: Fix impossible range checks -
`and` should be `or` for pageSize, partSize, and retry validation (a
value cannot be both less than MIN and greater than MAX simultaneously)
- **postgres.zig:14**: Fix copy-paste error where createConnection
function was internally named "createQuery"
## Test plan
- [ ] Verify S3 credential validation now properly rejects out-of-range
values for pageSize, partSize, and retry
- [ ] Verify libarchive seek operations work correctly
- [ ] Verify postgres createConnection function has correct internal
name
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Claude Bot <claude-bot@bun.sh>
## Summary
- Fixes#25903 - `Bun.write()` mode option ignored when copying from
`Bun.file()`
- The destination file now correctly uses the specified `mode` option
instead of default permissions
- Works on Linux (via open flags), macOS (chmod after clonefile), and
Windows (chmod after copyfile)
## Test plan
- [x] Added regression test in `test/regression/issue/25903.test.ts`
- [x] Test passes with `bun bd test test/regression/issue/25903.test.ts`
- [x] Test fails with `USE_SYSTEM_BUN=1 bun test
test/regression/issue/25903.test.ts` (verifies the bug exists)
## Changes
- `src/bun.js/webcore/Blob.zig`: Add `mode` field to `WriteFileOptions`
and parse from options
- `src/bun.js/webcore/blob/copy_file.zig`: Use `destination_mode` in
`CopyFile` struct and `doOpenFile`
- `packages/bun-types/bun.d.ts`: Add `mode` option to BunFile copy
overloads
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>