#15948: fix(logging): prevent recursive logger/config stack overflow
size: S
experienced-contributor
Cluster:
Hooks and UI Fixes
## Summary
- add reentrancy guard in logger settings resolution to avoid recursive config load when console capture logs during config failures
- ensure guard is always reset with a finally block and preserve Vitest default file-log level behavior
- add regression test that reproduces circular-include config failure under console capture and asserts no stack overflow
## Validation
- bun test src/logging/logger.import-side-effects.test.ts src/logging/logger.recursion-guard.test.ts src/index.test.ts --reporter=dot
- pnpm exec oxlint src/logging/logger.ts src/logging/logger.recursion-guard.test.ts
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
Prevents recursive stack overflow in logger settings resolution when config loading fails under console capture.
**Key changes:**
- Added `resolvingSettings` reentrancy guard flag in `logger.ts:20`
- Introduced `resolveFallbackSettings()` helper that returns safe defaults when recursion is detected
- Wrapped `resolveSettings()` in try/finally to ensure guard is always reset
- Added comprehensive regression test that reproduces circular `$include` failure scenario
**How it works:**
When console capture is enabled, console calls route through the file logger. If config loading fails and logs an error, that error would trigger another `getLogger()` call, creating infinite recursion. The guard detects reentry and returns fallback settings instead of recursing.
**Impact:**
This is a critical stability fix that prevents crashes during config loading failures, particularly in test environments with console capture enabled.
<h3>Confidence Score: 5/5</h3>
- Safe to merge - critical bug fix with no breaking changes
- This is a well-implemented fix for a critical stack overflow bug. The reentrancy guard pattern is standard and correct, using try/finally ensures the guard is always reset, and the fallback settings provide safe defaults. The regression test directly reproduces the failure scenario with a circular $include. No logic changes to normal operation - only adds protection for the error path.
- No files require special attention
<sub>Last reviewed commit: 0d8f9f3</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#12048: fix: deduplicate config warnings to log once instead of on every re...
by mcaxtr · 2026-02-08
79.3%
#11281: fix(logging): prevent subsystem loggers from bypassing file log lev...
by janckerchen · 2026-02-07
77.2%
#14179: fix(config): resolve $include directives before validation in setup...
by ken2190 · 2026-02-11
74.6%
#11549: lint: add no-console rule and migrate 5 files to structured logger
by vaibhavtupe · 2026-02-08
74.2%
#16991: fix(config): add missing defaults to config snapshot path
by AI-Reviewer-QS · 2026-02-15
73.8%
#15613: fix(config): align default pipelines across loadConfig and readConf...
by AI-Reviewer-QS · 2026-02-13
73.6%
#19510: fix(config): preserve configured values on invalid config validatio...
by yash27-lab · 2026-02-17
73.5%
#22478: fix(diagnostics-otel): wire OTLP exporter to emit traffic to config...
by LuffySama-Dev · 2026-02-21
73.5%
#22139: Fix(ui): improve log formatting for JSON payloads
by npmisantosh · 2026-02-20
73.2%
#9425: refactor(agents): replace console.warn with SubsystemLogger in comp...
by dinakars777 · 2026-02-05
73.2%