Skip to content

Fix PostgreSQL StringBuilder assertion failure with empty error messages - #22558

Merged
Jarred-Sumner merged 2 commits into
mainfrom
claude/fix-postgres-stringbuilder-assertion
Sep 11, 2025
Merged

Jarred-Sumner merged 2 commits into
mainfrom
claude/fix-postgres-stringbuilder-assertion

Conversation

@robobun

@robobun robobun commented Sep 10, 2025

Copy link
Copy Markdown
Collaborator

Summary

  • Fixed a debug build assertion failure in PostgreSQL error handling when all error message fields are empty
  • Added safety check before calling StringBuilder.allocatedSlice() to handle zero-length messages
  • Added regression test to prevent future occurrences

The Problem

When PostgreSQL sends an error response with completely empty message fields, the ErrorResponse.toJS function would:

  1. Calculate b.cap but end up with b.len = 0 (no actual content)
  2. Call b.allocatedSlice()[0..b.len] unconditionally
  3. Trigger an assertion in StringBuilder.allocatedSlice() that requires cap > 0

This only affected debug builds since the assertion is compiled out in release builds.

The Fix

Check if b.len > 0 before calling allocatedSlice(). If there's no content, use an empty string instead.

Test Plan

  • Added regression test that triggers the exact crash scenario
  • Verified test crashes without the fix (debug build)
  • Verified test passes with the fix
  • Confirmed release builds were not affected

🤖 Generated with Claude Code

When PostgreSQL returns an error response with completely empty message fields,
the ErrorResponse.toJS function would call StringBuilder.allocatedSlice() with
b.len == 0, triggering an assertion failure in debug builds.

This fix checks if b.len > 0 before calling allocatedSlice(), using an empty
string when there's no content to avoid the assertion.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
@robobun

robobun commented Sep 10, 2025 •

Copy link
Copy Markdown
Collaborator Author
Updated 5:56 PM PT - Sep 10th, 2025

❌ @autofix-ci[bot], your commit 902c7b0 has some failures in Build #25683


🧪   To try this PR locally:

bunx bun-pr 22558

That installs a local version of the PR into your bun-22558 executable, so you can run:

bun-22558 --bun

@coderabbitai

coderabbitai Bot commented Sep 10, 2025 •

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a safeguard in Postgres ErrorResponse.toJS to handle empty error messages without slicing past length, and introduces a regression test that simulates an empty Postgres error packet to ensure no crash under concurrent queries.

Changes

Cohort / File(s) Summary of changes
Postgres protocol error handling
src/sql/postgres/protocol/ErrorResponse.zig
Guard error message construction: pass an empty string when buffer length is zero instead of slicing allocatedSlice()[0..b.len]. Other fields to createPostgresError unchanged.
Regression test for empty error packet
test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
Adds a test that sends a minimal Postgres Error packet from a local TCP server, runs concurrent queries against it, expects errors, and verifies no crash occurs.

Possibly related PRs

Suggested reviewers

  • pfgithub
  • cirospaciari

Pre-merge checks (2 passed, 1 warning)

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title concisely and accurately summarizes the primary change: it fixes a PostgreSQL StringBuilder assertion failure caused by empty error messages. It is specific, focused, and appropriate for teammates scanning the project history.
Description Check ✅ Passed The description provides a clear summary, a problem statement, the implemented fix, and a detailed Test Plan that documents verification steps, which satisfies the template's intent for "what" and "how" even though the exact template headings are not used. All required information to review and verify the change is present and complete.
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/fix-postgres-stringbuilder-assertion

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (4)
test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts (4)

6-11: Use socket.end() to avoid racy partial writes

Destroying the socket immediately after write can drop bytes and introduce flakiness. End the socket gracefully so the tiny packet is flushed.

-    socket.write(createPostgresPacket("E", Buffer.from("\0"))); // Terminator only
-    socket.destroy();
+    socket.end(createPostgresPacket("E", Buffer.from("\0"))); // Terminator only, graceful FIN

32-38: Assert outcomes instead of a no-op assertion

Capture results and assert every query errored (coerced to null) rather than expect(true).

-  await Promise.all(promises);
-  await sql.close();
-  server.close();
-
-  // If we get here without crashing, the test passes
-  expect(true).toBe(true);
+  const results = await Promise.all(promises);
+  await sql.close();
+  await new Promise<void>(r => server.close(() => r()));
+
+  // Ensure all queries errored (we coerced to null)
+  expect(results.every(r => r === null)).toBe(true);

34-34: Wait for server to close before finishing the test

Awaiting close ensures clean teardown and reduces port/socket leaks in CI.

-  server.close();
+  await new Promise<void>(r => server.close(() => r()));

1-1: Consider encoding the tracking number in the filename

To align with the repo’s regression test organization (“organize by issue number”), consider renaming to include the PR/issue identifier, e.g., test/regression/issue/22558-postgres-stringbuilder-assertion-aggressive.test.ts.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4b5551d and 902c7b0.

📒 Files selected for processing (2)
  • src/sql/postgres/protocol/ErrorResponse.zig (1 hunks)
  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
test/**

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

Place all tests under the test/ directory

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
test/**/*.{js,ts}

📄 CodeRabbit inference engine (.cursor/rules/writing-tests.mdc)

test/**/*.{js,ts}: Write tests in JavaScript or TypeScript using Bun’s Jest-style APIs (test, describe, expect) and run with bun test
Prefer data-driven tests (e.g., test.each) to reduce boilerplate
Use shared utilities from test/harness.ts where applicable

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
test/**/*.test.ts

📄 CodeRabbit inference engine (test/CLAUDE.md)

test/**/*.test.ts: Name test files *.test.ts and use bun:test
Do not write flaky tests: never wait for arbitrary time; wait for conditions instead
Never hardcode port numbers in tests; use port: 0 to get a random port
When spawning Bun in tests, use bunExe() and bunEnv from harness
Prefer async/await in tests; for a single callback, use Promise.withResolvers()
Do not set explicit test timeouts; rely on Bun’s built-in timeouts
Use tempDir/tempDirWithFiles from harness for temporary files and directories in tests
For large/repetitive strings in tests, prefer Buffer.alloc(count, fill).toString() over "A".repeat(count)
Import common test utilities from harness (e.g., bunExe, bunEnv, tempDirWithFiles, tmpdirSync, platform checks, GC helpers)
In error tests, assert non-zero exit codes for failing processes and use toThrow for synchronous errors
Use describe blocks for grouping, describe.each for parameterized tests, snapshots with toMatchSnapshot, and lifecycle hooks (beforeAll, beforeEach, afterEach); track resources for cleanup in afterEach
Use using/await using with Bun resources (e.g., Bun.listen/connect/spawn/serve) to ensure cleanup in tests

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
test/regression/issue/**

📄 CodeRabbit inference engine (test/CLAUDE.md)

Place regression tests under test/regression/issue/ and organize by issue number

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
test/**/*.test.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

test/**/*.test.{ts,tsx}: Test files must be placed under test/ and end with .test.ts or .test.tsx
In tests, always use port: 0; do not hardcode ports or use custom random port functions
In tests, use normalizeBunSnapshot when asserting snapshots
Never write tests that merely assert absence of "panic" or "uncaught exception" in output
Avoid shell commands (e.g., find, grep) in tests; use Bun.Glob and built-ins instead
Prefer snapshot tests over exact stdout equality assertions

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
**/*.{js,ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Format JavaScript/TypeScript files with Prettier (bun run prettier)

Files:

  • test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts
src/**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/building-bun.mdc)

Implement debug logs in Zig using const log = bun.Output.scoped(.${SCOPE}, false); and invoking log("...", .{})

Files:

  • src/sql/postgres/protocol/ErrorResponse.zig
**/*.zig

📄 CodeRabbit inference engine (.cursor/rules/javascriptcore-class.mdc)

**/*.zig: Declare the extern C symbol in Zig and export a Zig-friendly alias for use
Wrap the Bun____toJS extern in a Zig method that takes a JSGlobalObject and returns JSC.JSValue

**/*.zig: Format Zig files with zig-format (bun run zig-format)
In Zig, manage memory carefully with allocators and use defer for cleanup

Files:

  • src/sql/postgres/protocol/ErrorResponse.zig
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Format
🔇 Additional comments (2)
src/sql/postgres/protocol/ErrorResponse.zig (1)

135-137: Fix avoids allocatedSlice() assert when buffer is empty — LGTM

The b.len guard correctly prevents calling allocatedSlice() with cap == 0. This addresses the debug-assert crash without affecting release behavior.

test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts (1)

16-20: Confirmed: SQL accepts max and connection_timeout (plus common aliases).
internal/sql/shared.ts normalizes options and reads options.max and options.connectionTimeout / options.connection_timeout / options.connectTimeout / options.connect_timeout (see src/js/internal/sql/shared.ts:465–472). packages/bun-types/sql.d.ts declares connectionTimeout/connection_timeout and max (see packages/bun-types/sql.d.ts:225,304).

@Jarred-Sumner
Jarred-Sumner merged commit 09c56c8 into main Sep 11, 2025
@Jarred-Sumner
Jarred-Sumner deleted the claude/fix-postgres-stringbuilder-assertion branch September 11, 2025 01:47
Jarred-Sumner pushed a commit that referenced this pull request Sep 29, 2026
### Problem

- An assert-enabled build (debug, ASAN) aborts with `panic: assertion
failed: self.cap > 0` in `StringBuilder::writable()`. `bun install`
reaches it with a hosted-git shortcut that ends at the colon, like
`"overrides": { "zz": "github:" }`.
- `allocate()` stores a pointer also for a count of 0 bytes.
`writable()` and `allocated_slice()`
(`src/bun_core/string/StringBuilder.rs:201-226`) asserted `cap > 0` for
each builder with a pointer.

### Fix

- `writable()` asserts `len <= cap`, the precondition of its pointer
arithmetic. This removes the abort.
- `allocated_slice()` loses the same assert. The Postgres call site
drops its #22558 guard and reads `written_slice()`. No path on main
fails there.
- Verified: `test/cli/install/hosted-git-info/`. On a debug build of
main, 5 install tests and the guard of 13 parser rows fail (timeouts).
All 18 pass with the fix. Two unit tests cover both views (Miri).
- Self-reviewed: 2 concerns raised, 2 addressed.

### Background

- `StringBuilder` counts each slice, allocates one buffer, then appends
into it.
- `HostedGitInfo` mirrors npm's hosted-git-info. Both return `project:
""` for `github:`. The tests record that output, not a new contract.
- Considered a guard in `HostedGitInfo::copy_from`. It adds a release
branch and leaves the assert false. Bake `computeChunks` (#20998) and
Postgres `ErrorResponse` (#22558) hit it before.

### Downsides

- Assert-enabled builds lose the `cap > 0` check. A builder that counted
nothing and appends bytes still panics on the bounds check.
- Release: 0 bytes changed in 4 `StringBuilder` symbols and 3 callers.
Only `error_response_jsc::to_js` changes: 4412 -> 4400 B.

<details><summary>Notes</summary>

**Origin.** A fuzzer found the abort on an assert-enabled build. No
issue exists. Only linux x64 was run.

**Proof runs (debug build).**

- Source of main (a4f1429): 5 of 5 new install tests fail. The
`beforeAll` hook of the 13 parser rows fails too, so these rows do not
run. Each failure shows `timed out after 5000ms`, not an assertion diff.
The child that aborts needs 5 s or more to print its stack trace. The
late output has `panic: assertion failed: self.cap > 0`.
- This PR: 18 of 18 pass.
- The new tests pass on a release build of main, because a release build
has no assert. `USE_SYSTEM_BUN=1` cannot show the failure.
-
`test/regression/issue/postgres-stringbuilder-assertion-aggressive.test.ts`
passes on main and on this PR. It does not tell the two apart.
- No caller reaches `allocated_slice()` with a zero-capacity buffer now.
The Postgres call site was the one caller that could, and it reads
`written_slice()`. `allocated_slice()` makes a slice over the whole
capacity, and only the first `len` bytes are written.
- Two unit tests in `StringBuilder.rs` take an empty builder through
`writable()`, `allocated_slice()`, `append()`, `written_slice()` and
`move_to_slice()`. `cargo miri test -p bun_core --lib string_builder`
runs them: 2 pass. With one of the old asserts back, 2 fail. CI does not
run them. `cargo test -p bun_core` does not link, and the Miri job does
not list `bun_core`, because other tests of that crate call foreign
functions.

**Measurements.** Release builds of main (a4f1429) and of this PR,
same toolchain.

- release code, 4 StringBuilder symbols and 3 inlining callers: 0 bytes
changed, 0 instructions differ (objdump). The symbols are
`StringBuilder::allocate`, `append`, `append_count`, `add_concat`,
`HostedGitInfo::from_url`, `HTTPClient::clone_metadata` and
`bun_picohttp::Response::clone`.
- release .text: +0 B (readelf, 58,143,477 B on main and on the PR).
`error_response_jsc::to_js`: 4412 -> 4400 B. It is the only one of
78,610 text symbols that changes size.
- from_url instructions per call (`github:user/repo#main`): 2596 -> 2596
(gdb `stepi` count over the call, JIT off). valgrind is not installed in
the container.
- allocator calls per from_url call: malloc 7, zalloc 1, realloc 0, free
7 on PR (main: 7, 1, 0, 7).
- syscalls, `bun install` on the override fixture: file 67 -> 67, read
18 -> 18, write 3 -> 3, network 0 -> 0 (gdb `catch syscall`). strace is
not installed in the container.
- assert-enabled checks per view call: `allocated_slice` 1 -> 0,
`writable` 1 -> 1.
- `len <= cap` in `writable()`: 0 assertion failures in 8 existing test
files on the debug build. The files are the three in
`test/cli/install/hosted-git-info/`,
`test/cli/install/overrides.test.ts`,
`test/bundler/bundler_compile.test.ts`,
`test/js/web/fetch/fetch.test.ts`, `test/js/bun/spawn/spawn.test.ts` and
the Postgres test above. `fetch.test.ts` has the same 25 failures on
main and on the PR. On the PR run, 2 more tests of
`bundler_compile.test.ts` and 4 more tests of `spawn.test.ts` reached
the 5000 ms timeout. All 6 pass with a longer timeout. The host had a
load average above 250 during the runs.

**Callers.** `bun_core::StringBuilder` has 27 construction sites in 18
files: 19 direct and 8 through `HeaderBuilder::default()`. `writable()`
has 10 callers outside the builder. Each one indexes the returned slice
with bounds checks and adds to `len` only what it wrote. So `len <= cap`
holds for them.

**Sites left as they are.**

- `src/runtime/valkey_jsc/js_valkey.rs:657-675` and
`src/bundler/linker_context/computeChunks.rs:551-555` skip the builder
when there is nothing to build. They also skip work, so they stay.
- Open PR #43942 sizes a buffer above the exact sum because of this
assert. It can use the exact sum after this PR.

**Tests.**

- The install tests are in
`hosted-git-info/boundary-conditions.test.ts`, not in
`overrides.test.ts`. That file installs from the public npm registry,
and these tests are about the spec parser.
- The `dependency github:` test records what release bun does for that
spec today. It sends one `GET /repos//tarball/` and exits with code 1.
The test uses a local server through `GITHUB_API_URL`.
- The expected objects in `from-url.test.ts` are the output of
hosted-git-info 9.0.0 on node 26.3.0 for the same 13 inputs.
- The 13 parser rows call the parser in the test process. A `beforeAll`
hook runs `bun install` with the override `github:` in a child process
first. An abort in the parser fails the hook, and the rows do not run. A
child process that imports `bun:internal-for-testing` needs 2 s to 5 s
on a debug build under load. That is too near the 5000 ms default.
- The `bun.lock` test compares each stderr line that names the lockfile.
`bun install` prints `Ignoring lockfile` and continues when it cannot
load `bun.lock`.
- One `bun install` covers the override values of all five providers.

**Differences from hosted-git-info 9.0.0 that this PR does not change.**

- `github:user/repo%2Egit`: the reference returns project `repo`, bun
returns `repo.git`.
- `github:%`: the reference returns `undefined`, `hostedGitInfo.fromUrl`
in bun throws `Invalid Git URL: InvalidURL`.
- `github:/.git`: the reference returns project `""`, bun returns `git`.
`new URL("github:/.git").pathname` is `git` in bun. Open PR #39457
covers that.

</details>

<!-- robobun:evidence:begin -->

---

**[human-review]** gate passed · iteration 1 · 4 files touched

<details><summary>fails on main (without fix)</summary>

```console
ASAN without fix: 6 failed, 32 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/pr_gate.xml" test/cli/install/hosted-git-info/boundary-conditions.test.ts test/cli/install/hosted-git-info/from-url.test.ts
bun test v1.4.3 (367d939)

test/cli/install/hosted-git-info/from-url.test.ts:
killed 1 dangling process
(fail) fromUrl > shortcuts with an empty user, project and committish > (unnamed) [5008.49ms]
  ^ a beforeEach/afterEach hook timed out for this test.
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:foo/bar [11.72ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:foo/bar#branch [4.62ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:user@foo/bar [3.28ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:user@foo/bar#branch [1.22ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:user:password@foo/bar [1.26ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket:user:password@foo/bar#branch [3.13ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket::password@foo/bar [0.94ms]
(pass) fromUrl > valid urls > bitbucket > parses bitbucket::password@foo/bar#branc
... (truncated)

release without fix: 32 skipped
bun test v1.4.3-canary.1 (6780601)

test/cli/install/hosted-git-info/from-url.test.ts:
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github: [2.39ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses gitlab: [0.07ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses bitbucket:
(pass) fromUrl > shortcuts with an empty user, project and committish > parses gist:
(pass) fromUrl > shortcuts with an empty user, project and committish > parses sourcehut: [1.02ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:.git [0.01ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:/
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:// [0.01ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:#
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:?x
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:@
(pass) fromUrl > shortcuts with an empty user, project and committish > parses
... (truncated)
```

</details>

<details><summary>passes on PR (with fix)</summary>

```console
ASAN with fix: 32 skipped
$ BUN_DEBUG_QUIET_LOGS=1 bun scripts/build.ts --profile=debug --quiet test "--reporter=junit" "--reporter-outfile=/tmp/pr_gate.xml" test/cli/install/hosted-git-info/boundary-conditions.test.ts test/cli/install/hosted-git-info/from-url.test.ts
bun test v1.4.3 (367d939)

test/cli/install/hosted-git-info/from-url.test.ts:
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github: [4.28ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses gitlab: [1.19ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses bitbucket: [0.91ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses gist: [0.75ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses sourcehut: [0.82ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:.git [1.52ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:/ [2.71ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses github:// [0.98ms]
(pass) fromUrl > shortcuts with an empty user, project and committish > parses git
... (truncated)

release with fix: 32 skipped
$ bun scripts/build.ts --profile=release
[configured] bun-profile → bun (stripped) in 6641ms (unchanged)
ninja: Entering directory `/workspace/bun/build/release'
[1/89] build.rs build_script_build
[2/89] rustc bun_platform 
[3/89] rustc bun_core 
[4/89] rustc bun_boringssl_sys 
[5/89] rustc bun_safety 
[6/89] rustc bun_cares_sys 
[7/89] rustc bun_zlib_sys 
[8/89] rustc bun_errno 
[9/89] rustc bun_picohttp 
[10/89] rustc bun_brotli 
[11/89] rustc bun_zstd 
[12/89] rustc bun_base64 
[13/89] rustc bun_ptr 
[14/89] rustc bun_output 
[15/89] rustc bun_valkey 
[16/89] rustc bun_clap 
[17/89] rustc bun_lsquic_sys 
[18/89] rustc bun_paths 
[19/89] rustc bun_tcc_sys 
[20/89] rustc bun_collections 
[21/89] rustc bun_shell_parser 
warning: `feature(generic_const_exprs)` is not supported with the next-generation trait solver
 --> src/shell_parser/lib.rs:1:30
  |
1 | #![feature(adt_const_params, generic_const_exprs, allocator_api)]
  |                              ^^^^^^^^^^^^^^^^^^^
  |
  = note: `-Znext-solver=globally` is currently enabled by default for testing
  = note: reverted the setting to `-Znext-solver=coherence` for this crate
  = note: the currently stable trait s
... (truncated)
```

</details>

<details><summary>diff hotspot</summary>

```
src/bun_core/string/StringBuilder.rs               | 30 +++++++-
 .../postgres/protocol/error_response_jsc.rs        |  8 +-
 .../hosted-git-info/boundary-conditions.test.ts    | 89 ++++++++++++++++++++++
 test/cli/install/hosted-git-info/from-url.test.ts  | 47 +++++++++++-
 4 files changed, 164 insertions(+), 10 deletions(-)
```

</details>

**gate history** · 1 passed · 0 rejected · iteration 1

<details><summary>evidence per changed file</summary>

```
file                                                      reads  edits  tests
src/bun_core/string/StringBuilder.rs                          2      1     35
src/sql_jsc/postgres/protocol/error_response_jsc.rs           2      2     27
…cli/install/hosted-git-info/boundary-conditions.test.ts      5      4     20
test/cli/install/hosted-git-info/from-url.test.ts             6      6     24
```

</details>

<!-- robobun:evidence:end -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants