#19996: fix(plugins): bind logger methods to preserve this context (#19988)
size: M
experienced-contributor
Cluster:
Plugin Enhancements and Fixes
## Summary
- **Bug**: Plugin SDK `normalizeLogger` destroys tslog `this`-binding
- **Root cause**: `normalizeLogger` in `src/plugins/registry.ts:465-470` destructures logger methods without `.bind()`, losing the `this` context
- **Fix**: Add `.bind(logger)` to all logger method assignments
Fixes #19988
## Problem
When `normalizeLogger` creates a new logger object by destructuring methods:
```typescript
const normalizeLogger = (logger: PluginLogger): PluginLogger => ({
info: logger.info, // ← loses `this`
warn: logger.warn,
error: logger.error,
debug: logger.debug,
});
```
The `this` binding is lost. Loggers like tslog that rely on internal state via `this` will throw or silently fail when `api.logger.*` is called inside plugins.
**Before fix (on main branch):**
```
Input: api.logger.info("test") // with tslog logger
Output: TypeError: Cannot read properties of undefined
```
## Changes
- `src/plugins/registry.ts` — Add `.bind(logger)` to preserve `this` context
- `src/plugins/logger-this-binding.test.ts` — Add regression tests
**After fix:**
```
Input: api.logger.info("test")
Output: (logs correctly)
```
## Test plan
- [x] New test: simulated `this`-dependent logger class
- [x] New test: real tslog `Logger` instance (`new Logger({ type: "hidden" })`)
- [x] Both tests fail on main, pass on fix branch
- [x] All 108 existing plugin tests pass
- [x] Lint passes
## Effect on User Experience
**Before:** Plugin authors using tslog see `api.logger.*` calls fail. They must implement workarounds (storing logger object, stderr fallback).
**After:** `api.logger.*` works correctly with any logger implementation including tslog.
Most Similar PRs
#22475: fix(logging): correct levelToMinLevel mapping to match tslog numbering
by ronaldslc · 2026-02-21
62.9%
#11281: fix(logging): prevent subsystem loggers from bypassing file log lev...
by janckerchen · 2026-02-07
62.7%
#12475: fix(logging): use Symbol.for for externalTransports to survive jiti...
by Yida-Dev · 2026-02-09
62.6%
#21721: fix: bind Slack slash options handler context
by AIflow-Labs · 2026-02-20
62.0%
#22478: fix(diagnostics-otel): wire OTLP exporter to emit traffic to config...
by LuffySama-Dev · 2026-02-21
62.0%
#19422: fix: pass session context to plugin tool hooks in toToolDefinitions
by namabile · 2026-02-17
61.8%
#16867: plugin-sdk: export PluginLogger type for plugin use
by fsdwen · 2026-02-15
60.1%
#19911: fix(slack): bind `this` context for `app.options()` in slash comman...
by myra-tapcart · 2026-02-18
59.9%
#14746: fix(hooks): use globalThis for handler registry to survive bundler ...
by openperf · 2026-02-12
59.5%
#19353: fix(diagnostics-otel): fix cross-chunk module isolation breaking even…
by nez · 2026-02-17
59.4%