## Summary
- Added documentation for worker_threads environmentData API and process
'worker' event
- Added documentation for --no-addons CLI flag
- Added documentation for RedisClient getBuffer() method
## Context
These features were released in Bun v1.2.13 but were missing from the
documentation.
🤖 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>
## Summary
Adds minimal documentation for features introduced in Bun v1.2.22 that
were previously undocumented.
## Changes
- Add `redis.hget()` example showing direct value return vs `hmget()`
array
- Add WebSocket subprotocol negotiation example with array syntax
- Mark bundler `onEnd` hook as implemented in plugins docs
- Add `bun run --workspaces` flag documentation
- Update `perf_hooks.monitorEventLoopDelay` as implemented in Node.js
APIs
- Add async stack traces note to debugger docs
- Document TTY access pattern after stdin closes
All changes are minimal - just code snippets or single-line mentions in
existing files. No new files created.
🤖 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>
## Summary
- Fixed segmentation fault when calling `toContainAnyKeys`,
`toContainKeys`, and `toContainAllKeys` on non-object values (null,
undefined, numbers, strings, etc.)
- Added proper validation to check if value is an object before calling
`hasOwnPropertyValue` or `keys()`
- Added comprehensive test coverage for edge cases
## Problem
The matchers were crashing with a segmentation fault when called with
non-object values because:
1. `toContainAnyKeys` and `toContainKeys` were calling
`hasOwnPropertyValue` without checking if the value is an object first
2. `toContainAllKeys` was calling `keys()` without checking if the value
is an object first
3. The `hasOwnPropertyValue` function documentation explicitly states:
"If the object is not an object, it will crash. **You must check if the
object is an object before calling this function.**"
## Solution
- Added `value.isObject()` check in `toContainAnyKeys` before attempting
to check for properties
- Fixed `toContainKeys` by replacing the `toBoolean()` check with
`isObject()` check
- Fixed `toContainAllKeys` by adding proper object validation before
calling `keys()`
- For non-objects with empty expected arrays, the matchers return true
(matching jest-extended behavior)
## Test plan
- [x] Added comprehensive test coverage in
`test/js/bun/test/expect.test.js`
- [x] Tests cover: null, undefined, numbers, strings, booleans, symbols,
BigInt, arrays, functions
- [x] All existing jest-extended tests continue to pass
- [x] Debug build compiles and all tests pass
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
### What does this PR do?
Missing `.t_equals` and `.t_slash` checks. This matches esbuild.
```go
// Returns true if the current less-than token is considered to be an arrow
// function under TypeScript's rules for files containing JSX syntax
func (p *parser) isTSArrowFnJSX() (isTSArrowFn bool) {
oldLexer := p.lexer
p.lexer.Next()
// Look ahead to see if this should be an arrow function instead
if p.lexer.Token == js_lexer.TConst {
p.lexer.Next()
}
if p.lexer.Token == js_lexer.TIdentifier {
p.lexer.Next()
if p.lexer.Token == js_lexer.TComma || p.lexer.Token == js_lexer.TEquals {
isTSArrowFn = true
} else if p.lexer.Token == js_lexer.TExtends {
p.lexer.Next()
isTSArrowFn = p.lexer.Token != js_lexer.TEquals && p.lexer.Token != js_lexer.TGreaterThan && p.lexer.Token != js_lexer.TSlash
}
}
// Restore the lexer
p.lexer = oldLexer
return
}
```
fixes#19697
### How did you verify your code works?
Added some tests.
### What does this PR do?
Fixes code like `[(()=>{})()][''+'c']`.
We were calling `visitExpr` on a node that was already visited. This
code doesn't exist in esbuild, but we should keep it because it's an
optimization.
fixes#18629fixes#15926
### How did you verify your code works?
Manually and added a test.
### What does this PR do?
esbuild returns `left` from the inner loop. This PR matches this
behavior. Before it was breaking out of the inner loop and continuing
through the outer loop, potentially parsing too far.
fixes#22013fixes#22384
### How did you verify your code works?
Added some tests.
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Given pattern input "../." we might collapse all path components.
### How did you verify your code works?
Manually and added a test.
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
### What does this PR do?
fix#23001 by removing references to old codelens from before the native
integration which should have its own (better and) native way of
starting
### How did you verify your code works?
## Summary
- Fixes V8StackTraceIterator terminating early when encountering stack
frames without parentheses (e.g., "at unknown")
- Ensures complete stack traces are shown by `Bun.inspect()` even after
`error.stack` property is accessed
- Addresses the root cause that PR #23022 was working around
## Problem
When the V8StackTraceIterator encountered a stack frame line without
parentheses (like `at unknown`), it would:
1. Set `offset = stack.length()`
2. Return `false`, terminating the entire iteration
3. Only parse frames before the "unknown" frame
This caused `Bun.inspect()` to show incomplete stack traces after the
`error.stack` property was accessed, as documented in issue discussions
around PR #23022.
## Solution
Changed the parser to continue iterating through subsequent frames
instead of terminating. Frames without parentheses are now treated as
having a source URL but no function name or location info.
## Test plan
- [x] Added regression test
`test/regression/issue/23022-stack-trace-iterator.test.ts`
- [x] Verified existing stack trace tests still pass
- [x] Manually tested with Node.js stream errors that trigger this code
path
### Before fix:
```
error: Socket is closed
code: "ERR_SOCKET_CLOSED"
at node:net:1322:32
```
### After fix:
```
error: Socket is closed
code: "ERR_SOCKET_CLOSED"
at unknown:1:1
at _write (node:net:1322:32)
at writeOrBuffer (internal:streams/writable:381:18)
at internal:streams/writable:334:16
at testStackTrace (/workspace/bun/test.js:8:10)
...
```
🤖 Generated with [Claude Code](https://claude.ai/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>
### What does this PR do?
fixes#7157, fixes#14662
migrates pnpm-workspace.yaml data to package.json & converts
pnpm-lock.yml to bun.lock
---
### How did you verify your code works?
manually, tests and real world examples
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
Currently, if you try to deinit an optional, `bun.memory.deinit` will
silently do nothing, even if the optional's payload is a struct with a
`deinit` method.
This commit makes sure the payload is deinitialized.
(For internal tracking: fixes STAB-1293)
### What does this PR do?
Previously `redis.subscribe` did not automatically connect, which was in
contrast to other Redis functions. This PR changes the necessary
`PUB/SUB` things so that `.subscribe` automatically connects.
### How did you verify your code works?
Didn't
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
it caused deploying the site to hang and `ref.ref(` isnt threadsafe. the
proper fix should latch onto the shell command instead of the generic
task queue
### What does this PR do?
Currently bundling and running projects with cyclic async module
dependencies will hang due to module promises never resolving. This PR
unblocks these projects by outputting `await Promise.all` with these
dependencies.
Before (will hang with bun, or error with unsettled top level await with
node):
```js
var __esm = (fn, res) => () => (fn && (res = fn((fn = 0))), res);
var init_mod3 = __esm(async () => {
await init_mod1();
});
var init_mod2 = __esm(async () => {
await init_mod1();
});
var init_mod1 = __esm(async () => {
await init_mod2();
await init_mod3();
});
await init_mod1();
```
After:
```js
var __esm = (fn, res) => () => (fn && (res = fn((fn = 0))), res);
var __promiseAll = Promise.all.bind(Promise);
var init_mod3 = __esm(async () => {
await init_mod1();
});
var init_mod2 = __esm(async () => {
await init_mod1();
});
var init_mod1 = __esm(async () => {
await __promiseAll([init_mod2(), init_mod3()]);
});
await init_mod1();
```
### How did you verify your code works?
Manually and tests
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
Fix tls property not being properly set
Fixes https://github.com/oven-sh/bun/issues/22186
### How did you verify your code works?
Tests + Manually test with upstash using `rediss` protocol and tls: true
options
---------
Co-authored-by: Marko Vejnovic <marko.vejnovic@hotmail.com>
Co-authored-by: Marko Vejnovic <marko@bun.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Reduce the size of `bun.webcore.Blob` from 120 bytes to 96. Also make it
ref-counted: in-progress work on improving the bindings generator
depends on this, as it means C++ can pass a pointer to the `Blob` to Zig
without risking it being destroyed if the GC collects the associated
`JSBlob`.
Note that this PR depends on #23013.
(For internal tracking: fixes STAB-1289, STAB-1290)
### What does this PR do?
Adds a max-concurrency flag to limit the amount of concurrent tests that
run at once. Defaults to 20. Jest and Vitest both default to 5.
### How did you verify your code works?
Tests
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Add a version of `ArrayList` that takes a generic `Allocator` type
parameter. This matches the interface of smart pointers like
`bun.ptr.Owned` and `bun.ptr.Shared`.
This type behaves like a managed `ArrayList` but has no overhead if
`Allocator` is a zero-sized type, like `bun.DefaultAllocator`.
(For internal tracking: fixes STAB-1267)
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Add `bun.ptr.ExternalShared`, a shared pointer whose reference count is
managed externally; e.g., by extern functions. This can be used to work
with `RefCounted` C++ objects in Zig. For example:
```cpp
// C++:
struct MyType : RefCounted<MyType> { ... };
extern "C" void MyType__ref(MyType* self) { self->ref(); }
extern "C" void MyType__ref(MyType* self) { self->deref(); }
```
```zig
// Zig:
const MyType = opaque {
extern fn MyType__ref(self: *MyType) void;
extern fn MyType__deref(self: *MyType) void;
pub const Ref = bun.ptr.ExternalShared(MyType);
// This enables `ExternalShared` to work.
pub const external_shared_descriptor = struct {
pub const ref = MyType__ref;
pub const deref = MyType__deref;
};
};
// Now `MyType.Ref` behaves just like `Ref<MyType>` in C++:
var some_ref: MyType.Ref = someFunctionReturningMyTypeRef();
const ptr: *MyType = some_ref.get(); // gets the inner pointer
var some_other_ref = some_ref.clone(); // increments the ref count
some_ref.deinit(); // decrements the ref count
// decrements the ref count again; if no other refs exist, the object
// is destroyed
some_other_ref.deinit();
```
This commit also adds `RawRefCount`, a simple wrapper around an integer
reference count that can be used to implement the interface required by
`ExternalShared`. Generally, for reference-counted Zig types,
`bun.ptr.Shared` is preferred, but occasionally it is useful to have an
“intrusive” reference-counted type where the ref count is stored in the
type itself. For this purpose, `ExternalShared` + `RawRefCount` is more
flexible and less error-prone than the deprecated `bun.ptr.RefCounted`
type.
(For internal tracking: fixes STAB-1287, STAB-1288)
## Summary
Improves server stability when handling certain request edge cases.
## Test plan
- Added regression test in `test/regression/issue/22353.test.ts`
- Test verifies server continues operating normally after handling edge
case requests
- All existing HTTP server tests pass
Fixes#22353🤖 Generated with [Claude Code](https://claude.ai/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>
### What does this PR do?
fixes an issue where fetch requests with `Content-Type:
application/x-www-form-urlencoded` would not include the request body in
curl logs when `BUN_CONFIG_VERBOSE_FETCH=curl` is enabled
previously, only JSON and text-based content types were recognized as
safe-to-print in the curl formatter. This change updates the allow-list
to also handle `application/x-www-form-urlencoded`, ensuring bodies for
common form submissions are shown in logs
### How did you verify your code works?
- added `Content-Type: application/x-www-form-urlencoded` to a fetch
request and confirmed that `BUN_CONFIG_VERBOSE_FETCH=curl` now outputs a
`--data-raw` section with the encoded body
- verified the fix against the reproduction script provided in issue
#12042
- created and ran a regression test
- checked that existing content types (JSON, text, etc.) continue to
print correctly
fixes#12042
### 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?
**This PR is created because [the previous PR I
opened](https://github.com/oven-sh/bun/pull/21728) had some concerning
issues.** Thanks @Jarred-Sumner for the help.
The goal of this PR is to introduce PUB/SUB functionality to the
built-in Redis client. Based on the fact that the current Redis API does
not appear to have compatibility with `io-redis` or `redis-node`, I've
decided to do away with existing APIs and API compatibility with these
existing libraries.
I have decided to base my implementation on the [`redis-node` pub/sub
API](https://github.com/redis/node-redis/blob/master/docs/pub-sub.md).
#### Random Things That Happened
- [x] Refactored the build scripts so that `valgrind` can be disabled.
- [x] Added a `numeric` namespace in `harness.ts` with useful
mathematical libraries.
- [x] Added a mechanism in `cppbind.ts` to disable static assertions
(specifically to allow `check_slow` even when returning a `JSValue`).
Implemented via `// NOLINT[NEXTLINE]?\(.*\)` macros.
- [x] Fixed inconsistencies in error handling of `JSMap`.
### How did you verify your code works?
I've written a set of unit tests to hopefully catch the major use-cases
of this feature. They all appear to pass.
#### Future Improvements
I would have a lot more confidence in our Redis implementation if we
tested it with a test suite running over a network which emulates a high
network failure rate. There are large amounts of edge cases that are
worthwhile to grab, but I think we can roll that out in a future PR.
### Future Tasks
- [ ] Tests over flaky network
- [ ] Use the custom private members over `_<member>`.
---------
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
### What does this PR do?
### How did you verify your code works?
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
- Fixed a double-free bug in the `createArgv` function in
`node_process.zig`
## Details
The `createArgv` function had two `defer allocator.free(args)`
statements:
- One on line 164
- Another on line 192 (now removed)
This would cause the same memory to be freed twice when the function
returned, leading to undefined behavior.
Fixes#22975
## Test plan
The existing process.argv tests should continue to pass with this fix.
🤖 Generated with [Claude Code](https://claude.ai/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: Dylan Conway <dylan.conway567@gmail.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Outputs the seed when randomizing. Adds --seed flag to reproduce a
random order. Seeds might not produce the same order across operating
systems / bun versions.
Fixes#11847
---------
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>
### What does this PR do?
### How did you verify your code works?
---------
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>
### What does this PR do?
This assertion is occasionally incorrect, and was originally added as a
workaround for lack of proper error handling in zig's std library. We've
seen fixed that so this assertion is no longer needed.
### 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?
Adds a `bun run build:debug:noasan` run script and deletes the `bun run
build:debug:asan` rule.
### How did you verify your code works?
Ran the change locally.
## Summary
Implements authenticode signature stripping for Windows PE files when
using `bun build --compile`, ensuring that generated executables can be
properly signed with external tools after Bun embeds its data section.
## What Changed
### Core Implementation
- **Authenticode stripping**: Removes digital signatures from PE files
before adding the .bun section
- **Safe memory access**: Replaced all `@alignCast` operations with safe
unaligned access helpers to prevent crashes
- **Hardened PE parsing**: Added comprehensive bounds checking and
validation throughout
- **PE checksum recalculation**: Properly updates checksums after
modifications
### Key Features
- Always strips authenticode signatures when using `--compile` for
Windows (uses `.strip_always` mode)
- Validates PE file structure according to PE/COFF specification
- Handles overlapping memory regions safely during certificate removal
- Clears `IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY` flag when stripping
signatures
- Ensures no unexpected overlay data remains after stripping
### Bug Fixes
- Fixed memory corruption bug using `copyBackwards` for overlapping
regions
- Fixed checksum calculation skipping 6 bytes instead of 4
- Added integer overflow protection in payload size calculations
- Fixed double alignment bug in `size_of_image` calculation
## Technical Details
The implementation follows the Windows PE/COFF specification and
includes:
- `StripMode` enum to control when signatures are stripped
(none/strip_if_signed/strip_always)
- Safe unaligned memory access helpers (`viewAtConst`, `viewAtMut`)
- Proper alignment helpers with overflow protection (`alignUpU32`,
`alignUpUsize`)
- Comprehensive error types for all failure cases
## Testing
- Passes all existing PE tests in
`test/regression/issue/pe-codesigning-integrity.test.ts`
- Compiles successfully with `bun run zig:check-windows`
- Properly integrated with StandaloneModuleGraph for Windows compilation
## Impact
This ensures Windows users can:
1. Use `bun build --compile` to create standalone executables
2. Sign the resulting executables with their own certificates
3. Distribute properly signed Windows binaries
Fixes issues where previously signed executables would have invalid
signatures after Bun added its embedded data.
---------
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 unnecessary regeneration of `bun_dependency_versions.h` on every
CMake run
- Only writes the header file when content actually changes
## Test plan
Tested locally by running CMake configuration multiple times:
1. First run generates the file (shows "Updated dependency versions
header")
2. Subsequent runs skip writing (shows "Dependency versions header
unchanged")
3. File modification timestamp remains unchanged when content is the
same
4. File is properly regenerated when deleted or when content changes
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>