- Change default from 'main' to 'HEAD' so users can test coverage
of uncommitted changes without committing first
- When base_branch is "HEAD", run `git diff HEAD` instead of
`git diff HEAD...HEAD` to show staged + unstaged changes
- Update tests to verify uncommitted changes detection
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Add end_ordinal.isValid() check when detecting uncovered functions
- Remove async keyword from synchronous helper functions in tests
- Fix line range collapsing to show separate ranges (e.g., "5, 10, 15" not "5-15")
- Skip coverage table output when CLAUDECODE=1 with --coverage-changes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Adds a new `--coverage-changes` CLI flag for `bun test` that reports code coverage
specifically for lines that changed compared to a base branch (default: main).
Features:
- Merged coverage table with "% Chang" column showing coverage for changed lines only
- AI agent detection (AGENT=1 or CLAUDECODE env) outputs XML prompts for uncovered code:
- `<file>` tags for uncovered line ranges
- `<function>` tags for entirely uncovered new functions with correct line numbers
- Exits with code 1 if changed lines coverage is below threshold (default 90%)
- Skips test files from changed lines tracking when coverageSkipTestFiles is enabled
- Uses bun.Ordinal for unambiguous line number handling (0-indexed internal, 1-indexed display)
Usage:
bun test --coverage --coverage-changes # Compare against main
bun test --coverage --coverage-changes=develop # Compare against develop
Example output with AI agent prompts (AGENT=1):
```
File | % Funcs | % Lines | % Chang | Uncovered Line #s
lib.ts | 50.00 | 66.67 | 0.00 |
Coverage for changed lines (0.00%) is below threshold (90.00%)
<errors>
<file path="lib.ts">
In lib.ts, lines 5 do not have test coverage. Write tests to cover these lines.
</file>
<function path="lib.ts" startLine="5" endLine="6">
In lib.ts, the function at lines 5-6 is never called. Write a test that calls this function, or delete it if it is dead code.
</function>
</errors>
```
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
### What does this PR do?
Ensures `ptr` is either a number or heap big int before converting to a
number.
also fixes ENG-24039
### How did you verify your code works?
Added a test
### What does this PR do?
Fixes checking for exceptions when creating empty or used readable
streams
also fixes ENG-24038
### How did you verify your code works?
Added a test for creating empty streams
## Summary
- Implements the `%j` format specifier for `console.log` and related
console methods
- `%j` outputs the JSON stringified representation of the value
- Previously, `%j` was not recognized and was left as literal text in
the output
## Test plan
- [x] Run `bun bd test test/regression/issue/24234.test.ts` - all 5
tests pass
- [x] Verify tests fail with system Bun (`USE_SYSTEM_BUN=1`) to confirm
fix validity
- [x] Manual verification: `console.log('%j', {foo: 'bar'})` outputs
`{"foo":"bar"}`
## Example
Before (bug):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
%j [object Object] hello
```
After (fixed):
```
$ bun -e "console.log('%j %s', {foo: 'bar'}, 'hello')"
{"foo":"bar"} hello
```
Closes#24234🤖 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
- Add proper bounds checking for encoding operations that produce larger
output than input
- Handle allocation failures gracefully by returning appropriate errors
- Add defensive checks in string initialization functions
## Test plan
- Added test case for encoding operations with large buffers
- Verified existing buffer tests still pass
🤖 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
Implements the [URLPattern Web
API](https://developer.mozilla.org/en-US/docs/Web/API/URLPattern) based
on WebKit's implementation. URLPattern provides declarative pattern
matching for URLs, similar to how regular expressions work for strings.
### Features
- **Constructor**: Create patterns from strings or `URLPatternInit`
dictionaries
- **`test()`**: Check if a URL matches the pattern (returns boolean)
- **`exec()`**: Extract matched groups from a URL (returns
`URLPatternResult` or null)
- **Pattern properties**: `protocol`, `username`, `password`,
`hostname`, `port`, `pathname`, `search`, `hash`
- **`hasRegExpGroups`**: Detect if the pattern uses custom regular
expressions
### Example Usage
```js
// Match URLs with a user ID parameter
const pattern = new URLPattern({ pathname: '/users/:id' });
pattern.test('https://example.com/users/123'); // true
pattern.test('https://example.com/posts/456'); // false
const result = pattern.exec('https://example.com/users/123');
console.log(result.pathname.groups.id); // "123"
// Wildcard matching
const filesPattern = new URLPattern({ pathname: '/files/*' });
const match = filesPattern.exec('https://example.com/files/image.png');
console.log(match.pathname.groups[0]); // "image.png"
```
## Implementation Notes
- Adapted from WebKit's URLPattern implementation
- Modified JS bindings to work with Bun's infrastructure (simpler
`convertDictionary` patterns, WTF::Variant handling)
- Added IsoSubspaces for proper GC integration
## Test Plan
- [x] 408 tests from Web Platform Tests pass
- [x] Tests fail with system Bun (URLPattern not defined), pass with
debug build
- [x] Manual testing of basic functionality
Fixes https://github.com/oven-sh/bun/issues/2286🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
## Summary
- Fix `bun publish --help` showing incorrect `--dry-run` description
("Don't install anything" → "Perform a dry run without making changes")
- The `--dry-run` flag is in a shared params array used by multiple
commands, so the new generic message works for all of them
Fixes#24806
## Test plan
- [x] Verify `bun publish --help` shows "Perform a dry run without
making changes" for --dry-run
- [x] Regression test added that validates the correct help text is
shown
- [x] Test passes with debug build, fails with system bun (validating it
tests the right thing)
🤖 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>
## Summary
- Make `Http2Server.setTimeout()` and `Http2SecureServer.setTimeout()`
return `this` to enable method chaining
- Matches Node.js behavior where `server.setTimeout(1000).listen()`
works
Fixes#24924
## Test plan
- [x] Test that `Http2Server.setTimeout()` returns server instance
- [x] Test that `Http2SecureServer.setTimeout()` returns server instance
- [x] Test method chaining works (e.g.,
`server.setTimeout(1000).close()`)
- [x] Tests pass with debug build, fail with system bun
🤖 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>
## Summary
- Adds stricter validation for chunk boundaries in the HTTP chunked
transfer encoding parser
- Ensures conformance with RFC 9112 requirements for chunk formatting
- Adds additional test coverage for chunked encoding edge cases
## Test plan
- Added new tests in `test/js/bun/http/request-smuggling.test.ts`
- All existing HTTP tests pass
- `bun bd test test/js/bun/http/request-smuggling.test.ts` passes
🤖 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
- Extends `fetch()` proxy option to accept an object format: `proxy: {
url: string, headers?: Headers }`
- Allows sending custom headers to the proxy server (useful for proxy
authentication, custom routing headers, etc.)
- Headers are sent in CONNECT requests (for HTTPS targets) and direct
proxy requests (for HTTP targets)
- User-provided `Proxy-Authorization` header overrides auto-generated
credentials from URL
## Usage
```typescript
// Old format (still works)
fetch(url, { proxy: "http://proxy.example.com:8080" });
// New object format with headers
fetch(url, {
proxy: {
url: "http://proxy.example.com:8080",
headers: {
"Proxy-Authorization": "Bearer token",
"X-Custom-Proxy-Header": "value"
}
}
});
```
## Test plan
- [x] Test proxy object with url string works same as string proxy
- [x] Test proxy object with headers sends headers to proxy (HTTP
target)
- [x] Test proxy object with headers sends headers in CONNECT request
(HTTPS target)
- [x] Test proxy object with Headers instance
- [x] Test proxy object with empty headers
- [x] Test proxy object with undefined headers
- [x] Test user-provided Proxy-Authorization overrides URL credentials
- [x] All existing proxy tests pass (25 total)
🤖 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
- Fix crash in `FormData.from()` when called with very large ArrayBuffer
input
- Add length check in C++ `toString` function against both Bun's
synthetic limit and WebKit's `String::MaxLength`
- For UTF-8 tagged strings, use simdutf to calculate actual UTF-16
length only when byte length exceeds the limit
## Root Cause
When `FormData.from()` was called with a very large ArrayBuffer (e.g.,
`new Uint32Array(913148244)` = ~3.6GB), the code would crash with:
```
ASSERTION FAILED: data.size() <= MaxLength
vendor/WebKit/Source/WTF/wtf/text/StringImpl.h(886)
```
The `toString()` function in `helpers.h` was only checking against
`Bun__stringSyntheticAllocationLimit` (which defaults to ~4GB), but not
against WebKit's `String::MaxLength` (INT32_MAX, ~2GB). When the input
exceeded `String::MaxLength`, `createWithoutCopying()` would fail with
an assertion.
## Changes
1. **helpers.h**: Added `|| str.len > WTF::String::MaxLength` checks to
all three code paths in `toString()`:
- UTF-8 tagged pointer path (with simdutf length calculation only when
needed)
- External pointer path
- Non-copying creation path
2. **url.zig**: Reverted the incorrect Zig-side check (UTF-8 byte length
!= UTF-16 character length)
## Test plan
- [x] Added test that verifies FormData.from with oversized input
doesn't crash
- [x] Verified original crash case now returns empty FormData instead of
crashing:
```js
const v3 = new Uint32Array(913148244);
FormData.from(v3); // No longer crashes
```
🤖 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
- Fix assertion failure in `Bun.mmap` when `offset` or `size` options
are non-numeric values
- Add validation to reject negative `offset`/`size` with clear error
messages
Minimal reproduction: `Bun.mmap("", { offset: null });`
## Root Cause
`Bun.mmap` was calling `toInt64()` directly on the `offset` and `size`
options without validating they are numbers first. `toInt64()` has an
assertion that the value must be a number or BigInt, which fails when
non-numeric values like `null` or functions are passed.
## Test plan
- [x] Added tests for negative offset/size rejection
- [x] Added tests for non-number inputs (null, undefined)
- [x] `bun bd test test/js/bun/util/mmap.test.js` passes
Closes ENG-22413
🤖 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
- Fix debug assertion failure in `JSWrappingFunction` when
`expect.extend()` is called with objects containing non-`JSFunction`
callables
- The crash occurred because `jsCast<JSFunction*>` was used, which
asserts the value inherits from `JSFunction`, but callable class
constructors (like `Expect`) inherit from `InternalFunction` instead
## Changes
- Change `JSWrappingFunction` to store `JSObject*` instead of
`JSFunction*`
- Use `jsDynamicCast` instead of `jsCast` in `getWrappedFunction`
- Use `getObject()` instead of `jsCast` in `create()`
## Reproduction
```js
const jest = Bun.jest();
jest.expect.extend(jest);
```
Before fix (debug build):
```
ASSERTION FAILED: !from || from->JSCell::inherits(std::remove_pointer<To>::type::info())
JSCast.h(40) : To JSC::jsCast(From *) [To = JSC::JSFunction *, From = JSC::JSCell]
```
After fix: Properly throws `TypeError: expect.extend: 'jest' is not a
valid matcher`
## Test plan
- [x] Added regression test
`test/regression/issue/fuzzer-ENG-22942.test.ts`
- [x] Existing `expect-extend.test.js` tests pass (27 tests)
- [x] Build succeeds
Fixes ENG-22942
🤖 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
Fixes#23292
`fs.access()` and `fs.accessSync()` threw EUNKNOWN (-134) when checking
named pipes on Windows (paths like `\.\pipe\name`), but Node.js worked
fine.
**Repro:**
```ts
// Server creates pipe at \.\pipe\bun-test
import net from 'net';
const server = net.createServer();
server.listen('\\.\pipe\bun-test');
// Client tries to check if pipe exists
import fs from 'fs';
fs.accessSync('\\.\pipe\bun-test', fs.constants.F_OK);
// Error: EUNKNOWN: unknown error, access '\.\pipe\bun-test'
```
## Root Cause
The `osPathKernel32` function normalizes paths before passing to Windows
APIs. The normalization logic treats a single `.` as a "current
directory" component and removes it, so `\.\pipe\name` incorrectly
became `\pipe\name` - an invalid path.
## Solution
Detect Windows device paths (starting with `\.\` or `\?\`) and skip
normalization for these special paths, preserving the device prefix.
## Test Plan
- [x] Added regression test `test/regression/issue/23292.test.ts`
- [x] Test fails with system bun (v1.3.3): 3 failures (EUNKNOWN)
- [x] Test passes with fix: 4 pass
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <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>
## Summary
Fixes a crash (ENG-22243) where calling class constructors marked with
`call: false` would create invalid instances instead of throwing an
error.
## Root Cause
When a class definition has `call: false` (like `Bun.RedisClient`), the
code generator was still allowing the constructor to be invoked without
`new`. This created invalid instances that caused a buffer overflow
during garbage collection.
## The Fix
Modified `src/codegen/generate-classes.ts` to properly check the `call`
property:
- When `call: false`: throws `TypeError: Class constructor X cannot be
invoked without 'new'`
- When `call: true`: behaves as before, allowing construction without
`new`
## Test Plan
- [x] Added regression test in `test/regression/issue/22243.test.ts`
- [x] Test fails with system bun (has the bug)
- [x] Test passes with fixed build
- [x] Verified `Bun.RedisClient()` now throws proper error
- [x] Verified `new Bun.RedisClient()` still works
## Before
```bash
$ bun -e "Bun.RedisClient()"
# Creates invalid instance, no error
```
## After
```bash
$ bun -e "Bun.RedisClient()"
TypeError: Class constructor RedisClient cannot be invoked without 'new'
```
🤖 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
- Fix `spyOn` crash when using indexed property keys (e.g., `spyOn(arr,
0)`)
## Test plan
- [x] Added tests for `spyOn` with numeric indexed properties
- [x] Added tests for `spyOn` with string indexed properties (e.g.,
`"0"`)
- [x] All existing `spyOn` tests pass
- [x] Full `mock-fn.test.js` test suite passes
Fixes ENG-21973
🤖 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
- Fix assertion failure when `Bun.indexOfLine` is called with a
non-number offset argument
- Changed from `.to(u32)` to `.coerce(i32, globalThis)` for proper
JavaScript type coercion
## Test plan
- [x] Added regression test in `test/js/bun/util/index-of-line.test.ts`
- [x] `bun bd test test/js/bun/util/index-of-line.test.ts` passes
Closes ENG-21997
🤖 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
- Skip 2 tests that use `grpctest.kleinsch.com` (domain no longer
exists)
- Fix flaky "should not keep repeating failed resolutions" test
These tests were originally skipped when added in #14286, but were
accidentally un-skipped in #20051. This restores them to match upstream
grpc-node.
## To re-enable these tests in the future
Bun could set up its own DNS TXT record at `*.bun.sh`. According to the
[gRPC A2
spec](https://github.com/grpc/proposal/blob/master/A2-service-configs-in-dns.md):
**DNS Setup needed:**
1. A record: `grpctest.bun.sh` → any valid IP (e.g., `127.0.0.1`)
2. TXT record: `_grpc_config.grpctest.bun.sh` with value:
```
grpc_config=[{"serviceConfig":{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"service":"MyService","method":"Foo"}],"waitForReady":true}]}}]
```
Then update the tests to use `grpctest.bun.sh` instead.
## Test plan
- [x] `bun bd test test/js/third_party/grpc-js/test-resolver.test.ts`
passes (20 pass, 3 skip, 1 todo, 0 fail)
🤖 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 a typo in `makeComponent` that incorrectly identified
2-character patterns starting with `.` (like `.*`) as `..` (DotBack)
patterns
- The condition checked `pattern[component.start] == '.'` twice instead
of checking both characters at positions 0 and 1
- This caused patterns like `.*/*` to be parsed as `../` + `*`, making
the glob walker traverse into parent directories
Fixes#24936
## Test plan
- [x] Added tests in `test/js/bun/glob/scan.test.ts` that verify
patterns like `.*/*` and `.*/**/*.ts` don't escape the cwd boundary
- [x] Tests fail with system bun (bug reproduced) and pass with the fix
- [x] All existing glob tests pass (169 tests)
🤖 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>
### What does this PR do?
Removes a TODO
### 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 was creating `Zig::FFIFunction` when we could instead use a plain
`JSC::JSFunction`
### How did you verify your code works?
Added a test
### What does this PR do?
`blob.stream(undefined)`
### How did you verify your code works?
Added a test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
### What does this PR do?
Fixes ENG-21490
### How did you verify your code works?
Added a test that would previously fail due to timeout. It also confirms
the parsed result is correct.
---------
Co-authored-by: taylor.fish <contact@taylor.fish>
### What does this PR do?
Makes sure we are creating error messages with an allocator that will
not `deinit` at the end of function scope on error.
fixes ENG-21528
### How did you verify your code works?
Added a test
## Summary
Implements `--no-env-file` CLI flag and bunfig configuration options to
disable automatic `.env` file loading at runtime and in the bundler.
## Motivation
Users may want to disable automatic `.env` file loading for:
- Production environments where env vars are managed externally
- CI/CD pipelines where .env files should be ignored
- Testing scenarios where explicit env control is needed
- Security contexts where .env files should not be trusted
## Changes
### CLI Flag
- Added `--no-env-file` flag that disables loading of default .env files
- Still respects explicit `--env-file` arguments for intentional env
loading
### Bunfig Configuration
Added support for disabling .env loading via `bunfig.toml`:
- `env = false` - disables default .env file loading
- `env = null` - disables default .env file loading
- `env.file = false` - disables default .env file loading
- `env.file = null` - disables default .env file loading
### Implementation
- Added `disable_default_env_files` field to `api.TransformOptions` with
serialization support
- Added `disable_default_env_files` field to `options.Env` struct
- Implemented `loadEnvConfig` in bunfig parser to handle env
configuration
- Wired up flag throughout runtime and bundler code paths
- Preserved package.json script runner behavior (always skips default
.env files)
## Tests
Added comprehensive test suite (`test/cli/run/no-envfile.test.ts`) with
9 tests covering:
- `--no-env-file` flag with `.env`, `.env.local`,
`.env.development.local`
- Bunfig configurations: `env = false`, `env.file = false`, `env = true`
- `--no-env-file` with `-e` eval flag
- `--no-env-file` combined with `--env-file` (explicit files still load)
- Production mode behavior
All tests pass with debug bun and fail with system bun (as expected).
## Example Usage
```bash
# Disable all default .env files
bun --no-env-file index.js
# Disable defaults but load explicit file
bun --no-env-file --env-file .env.production index.js
# Disable via bunfig.toml
cat > bunfig.toml << 'CONFIG'
env = false
CONFIG
bun index.js
```
## Files Changed
- `src/cli/Arguments.zig` - CLI flag parsing
- `src/api/schema.zig` - API schema field with encode/decode
- `src/options.zig` - Env struct field and wiring
- `src/bunfig.zig` - Config parsing with loadEnvConfig
- `src/transpiler.zig` - Runtime wiring
- `src/bun.js.zig` - Runtime wiring
- `src/cli/exec_command.zig` - Runtime wiring
- `src/cli/run_command.zig` - Preserved package.json script runner
behavior
- `test/cli/run/no-envfile.test.ts` - Comprehensive test suite
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
### What does this PR do?
Ensures strings that would parse as a number with leading zeroes aren't
emitted without quotes.
fixes#23691
### How did you verify your code works?
Added a test
### What does this PR do?
The assertion was too strict.
This pr changes to assertion to allow multiple of the same dependency id
to be present. Also changes all the assertions to debug assertions.
fixes#24510
### How did you verify your code works?
Manually, and added a new test
---------
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Marko Vejnovic <marko@bun.com>