Skip to content

fix(windows): implement bmalloc SystemHeap using mimalloc to fix GC crashes#28249

Closed
robobun wants to merge 3 commits into
mainfrom
claude/fix-windows-bmalloc-systemheap-22349
Closed

fix(windows): implement bmalloc SystemHeap using mimalloc to fix GC crashes#28249
robobun wants to merge 3 commits into
mainfrom
claude/fix-windows-bmalloc-systemheap-22349

Conversation

@robobun

@robobun robobun commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Adds a working SystemHeap implementation for Windows backed by mimalloc (BmallocSystemHeapOverride.cpp)
  • Sets Malloc=1 environment variable at startup to force bmalloc to route all allocations through SystemHeap
  • Adds #include <stdlib.h> to Windows C headers for _putenv access

Root cause

bmalloc's SystemHeap on Windows is completely unimplemented — every allocation method (malloc, memalign, realloc, free) calls RELEASE_BASSERT_NOT_REACHED(). When libpas/bmalloc triggers SystemHeap allocations during GC cycles under memory pressure, this causes segmentation faults that manifest in JSC's Structure::maxOffsetWriteBarrierBase::setMayBeNullStructureCache::createEmptyStructure code path.

This was originally fixed in #20931 by removing bmalloc.lib from Windows link targets. However, the WebKit update in #26381 re-added bmalloc.lib, reintroducing the crash. bmalloc.lib cannot simply be removed because WTF.lib references bmalloc symbols.

How the fix works

  1. BmallocSystemHeapOverride.cpp defines the same symbols as bmalloc.lib's SystemHeap.cpp.o, using mimalloc instead of the crashing stubs. Since object files are processed before static libraries, the linker uses these definitions.
  2. main.zig sets Malloc=1 via _putenv before any bmalloc allocation, causing bmalloc::Environment to enable SystemHeap for all allocations.

Test plan

  • Linux debug build compiles successfully (changes are no-ops on non-Windows due to #if BOS(WINDOWS) / Environment.isWindows guards)
  • Windows CI build should verify the fix compiles and links correctly
  • Standalone executable (e.g., Claude Code) should no longer crash under memory pressure on Windows

Closes #22349

🤖 Generated with Claude Code

@robobun

robobun commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator Author
Updated 3:15 PM PT - Mar 18th, 2026

❌ Your commit c598607e has 4 failures in Build #40047 (All Failures):


🧪   To try this PR locally:

bunx bun-pr 28249

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

bun-28249 --bun

@github-actions

Copy link
Copy Markdown
Contributor

Found 6 issues this PR may fix:

  1. Crash in bmalloc (pas_assertion_failed) on Windows x64 baseline in standalone executable #26982 - Direct bmalloc crash in standalone executable with same pas_assertion_failed error pattern under memory pressure
  2. webkit: re-add -DUSE_SYSTEM_MALLOC=ON to Windows prebuilts #28101 - Related upstream WebKit fix to re-add USE_SYSTEM_MALLOC for Windows prebuilts (coordinated solution)
  3. Segfault after ~24h idle on Windows 11 with sleep/wake cycles #28175 - Windows 11 segfault after extended runtime when memory pressure builds up in standalone executable
  4. Segfault after ~24h idle on Windows 11 with sleep/wake cycles (second instance) #28176 - Second instance of Windows 11 segfault during sleep/wake cycles in standalone executable
  5. Segfault (null pointer at 0x0) in long-running standalone executable on Windows after sustained memory pressure #26862 - Long-running standalone executable segfault with high page faults indicating memory allocator failure
  6. [Windows] N-API vtable corruption causes segfault, TUI escape, and orphaned processes in Bun v1.3.10 #27471 - Windows N-API vtable corruption during concurrent operations suggesting memory allocation issues in Claude Code

If this is helpful, consider adding Fixes # to the PR description to auto-close the issue on merge.

🤖 Generated with Claude Code

@coderabbitai

coderabbitai Bot commented Mar 18, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds a Windows-specific mimalloc-backed SystemHeap implementation and enables it at process startup by setting Malloc=1 via _putenv; documents why bmalloc.lib remains linked in CMake. Conditional LIBPAS integration and Windows build guards included.

Changes

Cohort / File(s) Summary
Build configuration
cmake/targets/BuildBun.cmake
Added explanatory comment above Windows WIN32 WebKit linkage noting WTF.lib references bmalloc symbols and that bmalloc.lib stays linked; documents that BmallocSystemHeapOverride.cpp provides a mimalloc-based override. No functional CMake changes.
Windows SystemHeap implementation
src/bun.js/bindings/BmallocSystemHeapOverride.cpp
Adds a Windows-specific bmalloc::SystemHeap implemented using mimalloc (malloc/memalign/realloc/free/scavenge/dump, large-object support, per-process cache). Provides conditional LIBPAS integration: full pas_system_heap_* APIs when BUSE(LIBPAS) enabled, and stubs otherwise. Exposes symbols to override unimplemented bmalloc stubs.
Startup and headers
src/c-headers-for-zig.h, src/main.zig
Includes <stdlib.h> under Windows to support _putenv; in main.zig sets Malloc=1 early on Windows via _putenv (asserts success) to force bmalloc to use the SystemHeap override before other allocator setup.
🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed Title accurately summarizes the main change: implementing a Windows bmalloc SystemHeap with mimalloc to fix GC crashes, directly addressing issue #22349.
Description check ✅ Passed Description covers the root cause, how the fix works, and test plan, but lacks explicit verification details beyond pending CI checks.
Linked Issues check ✅ Passed Changes implement the core requirements: BmallocSystemHeapOverride.cpp provides a functional SystemHeap using mimalloc, Malloc=1 env var is set via _putenv in main.zig, and Windows-specific guards prevent non-Windows impact, directly addressing issue #22349.
Out of Scope Changes check ✅ Passed All changes are directly related to fixing the Windows bmalloc SystemHeap issue: the override implementation, environment variable setup, header inclusion, and explanatory comments are all in-scope.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

📝 Coding Plan
  • Generate coding plan for human review comments

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: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/bun.js/bindings/BmallocSystemHeapOverride.cpp`:
- Around line 38-40: Add instrumentation parity with WebKit by including
<bmalloc/pas_mte.h> and wrapping all pas_system_heap allocation calls with
PAS_PROFILE(SYSTEM_HEAP_ALLOCATION, ...) and PAS_MTE_HANDLE before delegating to
SystemHeap::getExisting()->...; specifically update the functions
pas_system_heap_malloc, pas_system_heap_memalign, pas_system_heap_realloc and
their pas_system_heap_*_compact variants so each allocation/deallocation call is
wrapped with PAS_PROFILE and PAS_MTE_HANDLE to restore profiling/tagging
behavior.

In `@src/main.zig`:
- Around line 32-34: The call to _putenv("Malloc=1") inside the
Environment.isWindows branch currently discards the return value, allowing
silent failure; change this to check the return value from _putenv and handle
failure (e.g., log an error and exit or return an error) so that Malloc=1 is
guaranteed to be visible to convertEnvToWTF8 which reads GetEnvironmentStringsW;
update the Windows initialization flow that calls _putenv in src/main.zig to
detect a non‑zero/-1 return and fail fast (or clearly document and assert why
silent failure is acceptable).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb6b84d4-2e69-4f9f-86b2-a58c25a8c173

📥 Commits

Reviewing files that changed from the base of the PR and between a7e9abe and 3528751.

📒 Files selected for processing (4)
  • cmake/targets/BuildBun.cmake
  • src/bun.js/bindings/BmallocSystemHeapOverride.cpp
  • src/c-headers-for-zig.h
  • src/main.zig

Comment on lines +38 to +40
#if BENABLE(LIBPAS)
#include <bmalloc/pas_system_heap.h>
#endif

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.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

find . -name "BmallocSystemHeapOverride.cpp" -type f

Repository: oven-sh/bun

Length of output: 106


🏁 Script executed:

find . -name "SystemHeap.cpp" -type f

Repository: oven-sh/bun

Length of output: 37


🏁 Script executed:

wc -l ./src/bun.js/bindings/BmallocSystemHeapOverride.cpp

Repository: oven-sh/bun

Length of output: 110


🏁 Script executed:

cat -n ./src/bun.js/bindings/BmallocSystemHeapOverride.cpp

Repository: oven-sh/bun

Length of output: 8808


🌐 Web query:

site:raw.githubusercontent.com WebKit SystemHeap.cpp pas_system_heap_malloc PAS_PROFILE

💡 Result:

In WebKit’s Source/bmalloc/bmalloc/SystemHeap.cpp (commit 1034e0634fd9bc7f1413cea076d0536b0e7cf87c), the libpas glue defines pas_system_heap_malloc() and instruments it with PAS_PROFILE before delegating to SystemHeap:

  • pas_system_heap_malloc(size_t size):
    • gets auto systemHeap = SystemHeap::getExisting();
    • calls PAS_PROFILE(SYSTEM_HEAP_ALLOCATION, systemHeap, size, 0, pas_non_compact_allocation_mode);
    • returns systemHeap->malloc(size, FailureAction::ReturnNull); [1]

The corresponding declarations live in Source/bmalloc/libpas/src/libpas/pas_system_heap.h (same commit), declaring pas_system_heap_malloc, pas_system_heap_memalign, etc., as BEXPORT extern ... when PAS_BMALLOC is enabled. [2]

Sources: [1], [2]


🌐 Web query:

site:raw.githubusercontent.com WebKit SystemHeap.cpp PAS_MTE_HANDLE

💡 Result:

In WebKit’s repo, PAS_MTE_HANDLE appears in Source/bmalloc/bmalloc/SystemHeap.cpp (the pas_system_heap_* allocation wrappers), e.g. these functions call it:

  • pas_system_heap_malloc
  • pas_system_heap_memalign
  • pas_system_heap_realloc
  • pas_system_heap_malloc_compact
  • pas_system_heap_memalign_compact
  • pas_system_heap_realloc_compact [1]

Raw files:

https://raw.githubusercontent.com/WebKit/WebKit/main/Source/bmalloc/bmalloc/SystemHeap.cpp
https://raw.githubusercontent.com/WebKit/WebKit/main/Source/bmalloc/bmalloc/SystemHeap.h
```  [1][2]

**Sources:** [1] [2]

---



</details>

**Mirror the PAS_PROFILE and PAS_MTE_HANDLE instrumentation from WebKit's canonical SystemHeap.cpp.**

This override currently acts as a symbol-only replacement without the profiling/tagging behavioral parity. WebKit's `SystemHeap.cpp` wraps all `pas_system_heap_*` allocations with `PAS_PROFILE(SYSTEM_HEAP_ALLOCATION, ...)` and `PAS_MTE_HANDLE` before delegating. On Windows LIBPAS builds, dropping these hooks means profiling and tagging data is incomplete.

Add `#include <bmalloc/pas_mte.h>` at line 39, then wrap the allocation calls in all six functions (`pas_system_heap_malloc`, `memalign`, `realloc`, and their `_compact` variants at lines 174–207) with both profiling hooks before the `SystemHeap::getExisting()->` delegation to maintain instrumentation consistency.

<details>
<summary>♻️ Suggested parity patch</summary>

```diff
 `#if` BENABLE(LIBPAS)
+#include <bmalloc/pas_mte.h>
 `#include` <bmalloc/pas_system_heap.h>
 `#endif`
@@
 void* pas_system_heap_malloc(size_t size)
 {
-    return SystemHeap::getExisting()->malloc(size, FailureAction::ReturnNull);
+    auto systemHeap = SystemHeap::getExisting();
+    PAS_PROFILE(SYSTEM_HEAP_ALLOCATION, systemHeap, size, 0, pas_non_compact_allocation_mode);
+    PAS_MTE_HANDLE(SYSTEM_HEAP_ALLOCATION, systemHeap, size, 0, pas_non_compact_allocation_mode);
+    return systemHeap->malloc(size, FailureAction::ReturnNull);
 }

Apply the same pattern to memalign, realloc, and their *_compact variants.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/bun.js/bindings/BmallocSystemHeapOverride.cpp` around lines 38 - 40, Add
instrumentation parity with WebKit by including <bmalloc/pas_mte.h> and wrapping
all pas_system_heap allocation calls with PAS_PROFILE(SYSTEM_HEAP_ALLOCATION,
...) and PAS_MTE_HANDLE before delegating to SystemHeap::getExisting()->...;
specifically update the functions pas_system_heap_malloc,
pas_system_heap_memalign, pas_system_heap_realloc and their
pas_system_heap_*_compact variants so each allocation/deallocation call is
wrapped with PAS_PROFILE and PAS_MTE_HANDLE to restore profiling/tagging
behavior.

Comment thread src/main.zig
Comment thread src/main.zig
Comment on lines +32 to +34
if (Environment.isWindows) {
_ = _bun.c._putenv("Malloc=1");
}

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.

🟡 The _putenv("Malloc=1") call added to main.zig (line 33) to force bmalloc to route all allocations through SystemHeap/mimalloc is missing from the test entry point src/main_test.zig. The test binary's Windows init block (lines 25-34) has the same uv_replace_allocator and environ setup but lacks this call, so the test build won't get the full libpas bypass on Windows. Add _ = bun.c._putenv("Malloc=1"); before the uv_replace_allocator call in main_test.zig.

Extended reasoning...

What the bug is

This PR adds _putenv("Malloc=1") to src/main.zig to force bmalloc to use SystemHeap (backed by mimalloc) instead of libpas on Windows. However, Bun has two entry points: src/main.zig for the main binary and src/main_test.zig for the test binary (bun-*-test). The fix was only applied to the main entry point.

The specific code path

In main_test.zig:22-34, the main() function has a Windows initialization block that calls uv_replace_allocator and sets up environ/_environ, mirroring the same block in main.zig. The new _putenv("Malloc=1") call was added to main.zig before this block but was not replicated in main_test.zig.

Why existing code doesn't prevent it

The two entry points are completely separate files with duplicated initialization logic. Changes to one are not automatically reflected in the other. The PR description and commit only modified main.zig, leaving main_test.zig untouched.

Impact

Without Malloc=1 being set, bmalloc::Environment::isSystemHeapEnabled() returns false in the test binary, so libpas remains the primary allocator rather than being bypassed through SystemHeap/mimalloc. The crash itself is still prevented because BmallocSystemHeapOverride.cpp provides working SystemHeap implementations (so when SystemHeap IS invoked during GC, it uses mimalloc instead of crashing). However, the test binary does not get the full allocation routing through mimalloc that the PR intends.

Step-by-step proof

  1. Build the test binary on Windows (cmake with -DTEST=ON), which uses main_test.zig as the entry point.
  2. The test binary starts, enters main() at main_test.zig:22.
  3. The Windows block at line 25 runs uv_replace_allocator and sets environ, but never calls _putenv("Malloc=1").
  4. When bmalloc's Environment initializes, it checks for the Malloc env var, finds it unset, and does NOT enable SystemHeap for all allocations.
  5. libpas remains the primary allocator in the test binary, unlike the main binary where Malloc=1 causes all allocations to route through SystemHeap/mimalloc.

How to fix

Add _ = bun.c._putenv("Malloc=1"); at the beginning of the Windows block in main_test.zig, before the uv_replace_allocator call, matching what was done in main.zig.

…rashes

bmalloc's SystemHeap on Windows is unimplemented — all allocation methods
crash with RELEASE_BASSERT_NOT_REACHED. When libpas triggers SystemHeap
allocations during GC cycles under memory pressure, this causes segfaults
in JSC's Structure/WriteBarrier code paths.

This adds a working SystemHeap implementation backed by mimalloc that
overrides bmalloc.lib's crashing stubs at link time. Combined with setting
Malloc=1 at startup to force bmalloc to route through SystemHeap, this
bypasses libpas for all allocations on Windows.

Fixes #22349

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@robobun robobun force-pushed the claude/fix-windows-bmalloc-systemheap-22349 branch from dd6b2d3 to 77922fd Compare March 18, 2026 17:51
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@robobun

robobun commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator Author

Re: CodeRabbit review comments:

PAS_PROFILE/PAS_MTE_HANDLE (BmallocSystemHeapOverride.cpp): Intentionally omitted. These macros instrument Apple's Memory Tagging Extension and allocation profiling — neither is relevant on Windows. The upstream WebKit code only uses them in the Darwin path. Adding them here would add dead code with no benefit.

_putenv return value (main.zig): Good catch. Added an assert so failure is caught immediately rather than silently deferring to a crash later when bmalloc tries to use the unimplemented libpas path.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/bun.js/bindings/BmallocSystemHeapOverride.cpp`:
- Around line 108-118: In SystemHeap::freeLarge, using m_sizeMap[base] silently
inserts a zero-sized entry on misses causing vmDeallocate(base, 0) and potential
corruption; change the lookup to use m_sizeMap.find(base), RELEASE_BASSERT that
the iterator is not end(), read size from it->second, then erase the entry via
m_sizeMap.erase(it) before calling vmDeallocate; ensure RELEASE_BASSERT
references the find result so we only deallocate tracked allocations.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 983b1a5f-b3c6-4c3c-a002-18fce3f42fca

📥 Commits

Reviewing files that changed from the base of the PR and between 3528751 and c598607.

📒 Files selected for processing (4)
  • cmake/targets/BuildBun.cmake
  • src/bun.js/bindings/BmallocSystemHeapOverride.cpp
  • src/c-headers-for-zig.h
  • src/main.zig

Comment on lines +108 to +118
void SystemHeap::freeLarge(void* base)
{
if (!base)
return;

size_t size;
{
LockHolder locker(mutex());
size = m_sizeMap[base];
size_t numErased = m_sizeMap.erase(base);
RELEASE_BASSERT(numErased == 1);

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.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

header="$(fd 'SystemHeap\.h$' . | head -n1)"
test -n "$header"
echo "== inspecting ${header} =="
rg -n -C5 '\bclass SystemHeap\b|\bm_sizeMap\b|\btake\s*\(|\bfind\s*\(|\berase\s*\(' "$header"

Repository: oven-sh/bun

Length of output: 37


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# First, let's check the .cpp file directly
cpp_file="src/bun.js/bindings/BmallocSystemHeapOverride.cpp"
if [ ! -f "$cpp_file" ]; then
    echo "File not found at expected location"
    exit 1
fi

echo "=== Examining the .cpp file for includes and m_sizeMap usage ==="
head -n 150 "$cpp_file"

Repository: oven-sh/bun

Length of output: 4000


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for SystemHeap.h in the repository
echo "=== Looking for SystemHeap.h ==="
find . -name "SystemHeap.h" -type f 2>/dev/null | head -20

# Also search for bmalloc headers
echo -e "\n=== Looking for bmalloc directory ==="
find . -type d -name "bmalloc" 2>/dev/null | head -10

Repository: oven-sh/bun

Length of output: 126


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Search for any bmalloc references or comments
echo "=== Searching for bmalloc references in the repo ==="
rg -l "bmalloc" --type-list 2>/dev/null | head -10

# Look for any comments or documentation mentioning SystemHeap
echo -e "\n=== Searching for SystemHeap references ==="
rg "SystemHeap" --type-list 2>/dev/null | head -5

# Search within the cpp file for m_sizeMap or map container hints
echo -e "\n=== Searching for map/HashMap patterns in bindings directory ==="
fd "\.h$|\.cpp$" src/bun.js/bindings/ | xargs rg "sizeMap|HashMap|map<" 2>/dev/null | head -20

Repository: oven-sh/bun

Length of output: 107


🌐 Web query:

bmalloc SystemHeap m_sizeMap container type find method

💡 Result:

In WebKit’s bmalloc::SystemHeap, m_sizeMap is a C++ standard hash table:

  • Container type: std::unordered_map<void*, size_t> m_sizeMap; (maps the base pointer of a “large” VM allocation to its size). [1]

To look up an entry, use std::unordered_map::find:

auto it = m_sizeMap.find(base);
if (it != m_sizeMap.end()) {
    size_t size = it->second;
}

(Internally, the code also uses erase(base) when freeing a large allocation.) [2]

Sources:
[1] WebKit SystemHeap.h (declaration of m_sizeMap)
[2] WebKit SystemHeap.cpp (use of m_sizeMap for large alloc/free)


Use find() instead of operator[] to avoid silent insertion on lookup miss.

m_sizeMap[base] creates a default entry {base, 0} if base is not in the map. This means if a large allocation was never tracked (bug elsewhere), erase(base) still succeeds and returns 1, the assertion passes, but size is 0. This causes vmDeallocate(base, 0) to be called with an incorrect size, leading to memory corruption.

Replace with:

auto it = m_sizeMap.find(base);
RELEASE_BASSERT(it != m_sizeMap.end());
size_t size = it->second;
m_sizeMap.erase(it);

This ensures the allocation was actually tracked before proceeding.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/bun.js/bindings/BmallocSystemHeapOverride.cpp` around lines 108 - 118, In
SystemHeap::freeLarge, using m_sizeMap[base] silently inserts a zero-sized entry
on misses causing vmDeallocate(base, 0) and potential corruption; change the
lookup to use m_sizeMap.find(base), RELEASE_BASSERT that the iterator is not
end(), read size from it->second, then erase the entry via m_sizeMap.erase(it)
before calling vmDeallocate; ensure RELEASE_BASSERT references the find result
so we only deallocate tracked allocations.

@robobun

robobun commented Mar 18, 2026

Copy link
Copy Markdown
Collaborator Author

Re: CodeRabbit review on freeLarge (BmallocSystemHeapOverride.cpp:118): This is intentional — the code matches upstream WebKit's SystemHeap::freeLarge implementation exactly. The RELEASE_BASSERT(numErased == 1) on the next line already catches the case where base isn't tracked. Diverging from upstream would make future WebKit updates harder to reconcile.

@robobun

robobun commented Mar 22, 2026

Copy link
Copy Markdown
Collaborator Author

Closing as duplicate of #28230 — nearly identical BmallocSystemHeapOverride.cpp implementation using mimalloc with Malloc=1 env var.

@robobun robobun closed this Mar 22, 2026
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.

claude code force close in windows powershell

1 participant