#21721: fix: bind Slack slash options handler context
channel: slack
size: S
Cluster:
Slack Thread Management Fixes
## What this fixes
Closes #21715.
Slack Socket Mode can crash on startup due to invoking Slack Bolt `App.options` with a detached context (`this` undefined) during external select argument menu registration.
## Root cause
`ctx.app.options` is extracted and invoked without binding in `registerArgOptions`.
## Fix
Bind the method to `ctx.app` before registration:
```ts
const optionsHandler = (ctx.app as unknown as { options?: (...) => void }).options?.bind(ctx.app);
```
This preserves the method context and avoids runtime `Cannot read properties of undefined (reading 'listeners')`.
## Validation
- `pnpm test src/slack/monitor/slash.test.ts`
- `pnpm test`
- `pnpm tsgo`
- `pnpm check`
## Notes
Added regression coverage in `src/slack/monitor/slash.test.ts` to assert option registration receives bound `app` context.
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Fixed a critical runtime bug where Slack Socket Mode would crash on startup due to `this` context loss when registering external select menu options. The root cause was extracting the `options` method from `ctx.app` without binding it, causing `Cannot read properties of undefined (reading 'listeners')` errors when Slack Bolt attempted to access `this.listeners` internally.
The fix applies `.bind(ctx.app)` to preserve method context, consistent with how Slack Bolt's `App` class expects its methods to be called. Added regression test that validates the `options` handler receives proper `this` binding.
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge with minimal risk
- The fix addresses a clear bug (method context loss) with a standard JavaScript solution (`.bind()`), adds appropriate regression test coverage, and follows the same pattern used elsewhere in the codebase where methods are called directly. The change is minimal, focused, and prevents a production crash.
- No files require special attention
<sub>Last reviewed commit: 7763038</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#19911: fix(slack): bind `this` context for `app.options()` in slash comman...
by myra-tapcart · 2026-02-18
89.7%
#21809: fix(slack): prevent native command startup crash on options registr...
by graysurf · 2026-02-20
83.5%
#17879: fix: prevent Slack auth errors from crashing the entire gateway
by zuyan9 · 2026-02-16
75.3%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
75.1%
#19083: Slack: preserve per-thread context and consistent thread replies
by jkimbo · 2026-02-17
73.9%
#22096: fix(slack): traverse .original for Slack SDK errors; pass recipient...
by maiclaw · 2026-02-20
73.6%
#21967: Harden Slack allow-from resolution against undefined catch crash
by graysurf · 2026-02-20
72.9%
#12369: fix: register unhandled rejection handler for Slack monitor
by Yida-Dev · 2026-02-09
72.7%
#23799: fix(slack): finalize replyToMode off threading behavior
by vincentkoc · 2026-02-22
72.3%
#21754: slack: pass inbound team_id into stream routing and startStream
by AIflow-Labs · 2026-02-20
72.3%