Bug Description
On Windows with PowerShell 5.1, settings.json is written with a UTF-8 BOM (EF BB BF). Node.js's JSON parser treats the BOM byte as an unrecognized token, causing the worker to fail loading its config on every startup.
Error Message
[LOGGER] Failed to load log level from settings: JSON Parse error: Unrecognized token ''
claude-mem worker unreachable for N consecutive hooks.
The empty string in Unrecognized token '' is the invisible BOM character ().
Root Cause
PowerShell 5.1 (Windows PowerShell, not PowerShell Core) defaults to UTF-8 with BOM for certain write operations. When settings.json is written by PowerShell-based tooling, the BOM is prepended.
Confirmed via:
$bytes = [System.IO.File]::ReadAllBytes("$env:USERPROFILE\.claude-mem\settings.json")
# Result: first 3 bytes = 0xEF 0xBB 0xBF (UTF-8 BOM)
# File content is structurally valid JSON — BOM prefix breaks the parser
Impact
- Worker fails to start on every Claude Code session restart
- Each hook call waits for timeout before failing → massive latency penalty on all tool calls (Glob, Read, Grep, Agent, etc.)
- After 24 consecutive failures,
CAPTURE_BROKEN flag is set and worker is permanently disabled until manual reset
- Only workaround: manually change port + reset
hook-failures.json + delete CAPTURE_BROKEN
- Long-running Agent tasks accumulate the full timeout overhead on every single tool call
Suggested Fixes
Option 1 — strip BOM on read (minimal change):
const raw = fs.readFileSync(settingsPath, 'utf8').replace(/^/, '');
const settings = JSON.parse(raw);
Option 2 — enforce utf8 without BOM on write (preferred):
fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), { encoding: 'utf8' });
// Node.js fs.writeFileSync with 'utf8' never writes a BOM
Option 3 — self-healing recovery (bonus):
Instead of setting CAPTURE_BROKEN permanently after N failures, auto-reset consecutiveFailures so the worker retries on next session start.
Environment
- OS: Windows 11 Pro 10.0.26200
- Shell: PowerShell 5.1 (Windows PowerShell)
- Node.js: invoked via
bun-runner.js → worker-service.cjs
- Claude Code: latest
Related
On Windows, TCP sockets enter TIME_WAIT state (default 240s) after the worker process exits abnormally. This compounds the BOM issue: even if the JSON bug were fixed, the port remains unavailable for ~4 minutes after a crash. Workaround: set TcpTimedWaitDelay=30 in the Windows registry to reduce TIME_WAIT to 30s.
Bug Description
On Windows with PowerShell 5.1,
settings.jsonis written with a UTF-8 BOM (EF BB BF). Node.js's JSON parser treats the BOM byte as an unrecognized token, causing the worker to fail loading its config on every startup.Error Message
The empty string in
Unrecognized token ''is the invisible BOM character ().Root Cause
PowerShell 5.1 (Windows PowerShell, not PowerShell Core) defaults to UTF-8 with BOM for certain write operations. When
settings.jsonis written by PowerShell-based tooling, the BOM is prepended.Confirmed via:
Impact
CAPTURE_BROKENflag is set and worker is permanently disabled until manual resethook-failures.json+ deleteCAPTURE_BROKENSuggested Fixes
Option 1 — strip BOM on read (minimal change):
Option 2 — enforce utf8 without BOM on write (preferred):
Option 3 — self-healing recovery (bonus):
Instead of setting
CAPTURE_BROKENpermanently after N failures, auto-resetconsecutiveFailuresso the worker retries on next session start.Environment
bun-runner.js→worker-service.cjsRelated
On Windows, TCP sockets enter TIME_WAIT state (default 240s) after the worker process exits abnormally. This compounds the BOM issue: even if the JSON bug were fixed, the port remains unavailable for ~4 minutes after a crash. Workaround: set
TcpTimedWaitDelay=30in the Windows registry to reduce TIME_WAIT to 30s.