#19911: fix(slack): bind `this` context for `app.options()` in slash command arg menus
channel: slack
size: XS
Cluster:
Slack Thread Management Fixes
## Problem
Since v2026.2.17, the Slack channel provider crashes immediately on startup with:
```
[default] channel exited: Cannot read properties of undefined (reading 'listeners')
```
The provider enters a 1/10 → 10/10 crash loop and never recovers. Slack is completely non-functional.
## Root Cause
`registerSlackMonitorSlashCommands` → `registerArgOptions()` destructures `ctx.app.options` into a local variable:
```typescript
const optionsHandler = (ctx.app as unknown as { options?: ... }).options;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// detached from `this` — classic JS footgun
optionsHandler(SLACK_COMMAND_ARG_ACTION_ID, ...);
// `this` is `undefined` inside Bolt's App.options()
```
Bolt's [`App.options()`](https://github.com/slackapi/bolt-js/blob/main/src/App.ts#L849) pushes to `this.listeners`, but `this` is `undefined` because the method was called without its receiver.
Other Bolt methods in the same file (`ctx.app.action()`, `ctx.app.command()`, `ctx.app.view()`) are called directly on the app instance and work fine. Only `options` was destructured.
## Fix
```diff
- ).options;
+ ).options?.bind(ctx.app);
```
One-line fix. Preserves `this` binding. The optional chain (`?.`) keeps the existing guard for environments where `options` may not exist.
## Stack Trace
```
TypeError: Cannot read properties of undefined (reading 'listeners')
at options (App.ts:849:10)
at registerArgOptions (subagent-registry-DN6TUJw4.js:48854:3)
at registerSlackMonitorSlashCommands (subagent-registry-DN6TUJw4.js:48881:2)
at monitorSlackProvider (subagent-registry-DN6TUJw4.js:49075:2)
```
## Verification
Patched the bundled dist on a live 2026.2.17 instance. Before: crash loop. After: `slack socket mode connected` — full inbound/outbound working.
## Affected Versions
- **Broken:** v2026.2.17
- **Working:** v2026.2.15
Fixes #19788
Ref: #8404
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
One-line fix for a critical crash-loop in the Slack channel provider introduced in v2026.2.17. The `App.options()` method from `@slack/bolt` was destructured into a local variable, detaching it from its `this` context. Since Bolt's `App.options()` internally accesses `this.listeners`, calling the detached method throws `Cannot read properties of undefined (reading 'listeners')`, crashing the provider on startup.
- Adds `.bind(ctx.app)` when extracting `options` from the Bolt app instance, preserving the method's `this` context
- The `?.` optional chain is retained so environments where `options` doesn't exist continue to work via the existing `typeof optionsHandler !== "function"` guard
- Other Bolt methods (`ctx.app.command()`, `ctx.app.action()`) are called directly on the instance and were unaffected
<h3>Confidence Score: 5/5</h3>
- This PR is safe to merge — it is a minimal, well-understood one-line fix for a critical crash-loop regression.
- The fix is a single-line change that correctly addresses a classic JS `this`-binding issue. The root cause and solution are clear, the author verified it on a live instance, and the change has no side effects on surrounding code. No new logic or risk is introduced.
- No files require special attention.
<sub>Last reviewed commit: cf31361</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
#21721: fix: bind Slack slash options handler context
by AIflow-Labs · 2026-02-20
89.7%
#21809: fix(slack): prevent native command startup crash on options registr...
by graysurf · 2026-02-20
86.2%
#20406: fix(slack): respect replyToMode when computing statusThreadTs in DMs
by QuinnYates · 2026-02-18
75.9%
#17879: fix: prevent Slack auth errors from crashing the entire gateway
by zuyan9 · 2026-02-16
75.8%
#22096: fix(slack): traverse .original for Slack SDK errors; pass recipient...
by maiclaw · 2026-02-20
74.2%
#20479: fix(slack): keep replies flowing for oversized file uploads
by olyashok · 2026-02-19
73.9%
#19083: Slack: preserve per-thread context and consistent thread replies
by jkimbo · 2026-02-17
73.5%
#21967: Harden Slack allow-from resolution against undefined catch crash
by graysurf · 2026-02-20
73.0%
#12369: fix: register unhandled rejection handler for Slack monitor
by Yida-Dev · 2026-02-09
72.5%
#8024: fix(slack): resolve channel names via directory for cross-account m...
by emma-digital-assistant · 2026-02-03
72.4%