fix(slack-work-app): Mimic nango behavior in socket mode#2172
fix(slack-work-app): Mimic nango behavior in socket mode#2172miles-kt-inkeep merged 4 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
1 Skipped Deployment
|
🦋 Changeset detectedLatest commit: ea885f1 The changes in this PR will be included in the next version bump. This PR includes changesets to release 9 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
There was a problem hiding this comment.
PR Review Summary
(5) Total Issues | Risk: High
🔴❗ Critical (1) ❗🔴
Inline Comments:
- 🔴 Critical:
commands/index.ts:299-304Behavioral regression — tenant-scoped lookup replaces tenant-agnostic lookup, breaking multi-tenant user resolution
🟠⚠️ Major (2) 🟠⚠️
Inline Comments:
- 🟠 Major:
dev-config.ts:78-84Silent failure — malformed default_agent JSON is swallowed without logging - 🟠 Major:
nango.ts:224-230Silent fallthrough when dev config is unreadable creates confusing failure modes
🟡 Minor (2) 🟡
🟡 1) dev-config.ts Module-level mutable state prevents test isolation
Issue: The module caches state in five module-level variables (cachedConfig, cacheExpiresAt, resolvedConfigPath, devModeChecked, devModeResult) with no reset mechanism. devModeChecked/devModeResult are computed once and never recomputed.
Why: Tests cannot reset state between runs, and the dev mode check is immutable for the process lifetime. The peer github/config.ts exports clearConfigCache() for this purpose.
Fix: Add a cache reset function for testing:
export function _resetDevConfigForTesting(): void {
cachedConfig = null;
cacheExpiresAt = 0;
resolvedConfigPath = undefined;
devModeChecked = false;
devModeResult = false;
}Refs:
🟡 2) dev-config.ts Missing tests for new module (~100 lines)
Issue: The new dev-config.ts module introduces file-based config loading, caching, and dev mode detection with no corresponding test file. The peer github/config.ts has comprehensive tests at __tests__/github/config.test.ts.
Why: The isSlackDevMode() function is the master switch for dev vs production behavior across 10+ code paths in nango.ts. A bug here has cascading effects. The JSON parsing in loadSlackDevConfig() and getDevDefaultAgent() have error paths that should be verified.
Fix: Add a test file at packages/agents-work-apps/src/__tests__/slack/dev-config.test.ts covering:
isSlackDevMode()behavior with various ENVIRONMENT + file combinationsloadSlackDevConfig()caching and error handlingsaveSlackDevConfig()persistencegetDevDefaultAgent()JSON parsing edge cases
Refs:
💭 Consider (2) 💭
💭 1) dev-config.ts:12-24 Missing Zod validation for SlackDevConfig
Issue: The interface is defined without Zod validation; JSON is cast with as SlackDevConfig without runtime checking.
Why: The peer github/config.ts uses GitHubAppConfigSchema with Zod for better error messages on malformed config. Consider adding for consistency.
💭 2) workspace-tokens.ts Potentially orphaned file
Issue: The workspace-tokens.ts file still exists and is exported from services/index.ts, but its primary consumer (getBotTokenForTeam in app-mention.ts) was removed. The module comment says it's a "temporary fallback."
Why: If this fallback path is no longer needed, consider removing the file to avoid confusion. If it's still used elsewhere, no action needed.
🚫 REQUEST CHANGES
Summary: The critical behavioral change in handleQuestionCommand (switching from tenant-agnostic to tenant-scoped user lookup) appears to be an unintentional regression that could break multi-tenant scenarios. The removed comments explicitly documented why the tenant-agnostic lookup was necessary. Please verify this change was intentional, and if not, revert to using findWorkAppSlackUserMappingBySlackUser. The silent error handling issues in the new dev-config module should also be addressed to improve debuggability during local development.
Discarded (12)
| Location | Issue | Reason Discarded |
|---|---|---|
nango.ts:193 |
Hardcoded 'default' tenantId | Matches .env.example convention (TENANT_ID=default) for local dev — appropriate behavior |
nango.ts:389-393 |
Added last_updated_at metadata | Minor enhancement consistent with existing pattern at line 559 — not a concern |
dev-config.ts:9-10 |
5-second cache TTL | Appropriate for local dev hot-reloading — shorter than production 60s TTL is intentional |
dev-config.ts:52-56 |
Dev mode detection pattern | Consistent with existing env.ENVIRONMENT === 'development' pattern used in 10+ locations |
nango.ts:111-114 |
createConnectSession returns null in dev | Expected behavior, documented in function — not confusing |
app-mention.ts:101-105 |
Removed fallback to workspace-tokens | Dev mode now handled in nango.ts — architecture simplification |
.gitignore:45 |
.slack-dev.json gitignore | Already properly ignored — no action needed |
changeset |
Vague message | Minor style issue, not blocking |
nango.ts:379-384 |
updateConnectionMetadata dev mode | Returns false without context log — covered by loadSlackDevConfig error |
nango.ts:405-415 |
setWorkspaceDefaultAgent dev mode | Same pattern as above — minor |
nango.ts:633-647 |
listWorkspaceInstallations dev mode | Returns valid shape — no issue |
nango.ts:288-292 |
Pre-existing silent catch | Not introduced by this PR — out of scope |
Reviewers (5)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-standards |
3 | 0 | 0 | 0 | 1 | 0 | 2 |
pr-review-consistency |
7 | 1 | 1 | 0 | 1 | 0 | 4 |
pr-review-tests |
8 | 1 | 0 | 0 | 0 | 0 | 7 |
pr-review-errors |
6 | 0 | 0 | 0 | 1 | 0 | 5 |
pr-review-devops |
7 | 0 | 1 | 0 | 0 | 0 | 6 |
| Total | 31 | 2 | 2 | 0 | 3 | 0 | 24 |
| if (isSlackDevMode()) { | ||
| const devConfig = loadSlackDevConfig(); | ||
| if (devConfig) { | ||
| logger.debug({ teamId }, 'Using .slack-dev.json for workspace connection'); | ||
| return buildDevWorkspaceConnection(devConfig, teamId); | ||
| } | ||
| } |
There was a problem hiding this comment.
🟠 MAJOR: Silent fallthrough when dev config is unreadable
Issue: When isSlackDevMode() returns true but loadSlackDevConfig() returns null (file unreadable, invalid JSON, permissions issue), the code silently falls through to attempt production Nango/PostgreSQL lookups.
Why: This creates a confusing state: the system believes it's in dev mode (config file path was found) but cannot read the config. Instead of receiving a clear error, the system attempts production lookups which will fail differently (no Nango credentials in dev) or unexpectedly succeed if production credentials happen to be configured.
Fix: Make the fallthrough explicit with a warning log:
| if (isSlackDevMode()) { | |
| const devConfig = loadSlackDevConfig(); | |
| if (devConfig) { | |
| logger.debug({ teamId }, 'Using .slack-dev.json for workspace connection'); | |
| return buildDevWorkspaceConnection(devConfig, teamId); | |
| } | |
| } | |
| if (isSlackDevMode()) { | |
| const devConfig = loadSlackDevConfig(); | |
| if (devConfig) { | |
| logger.debug({ teamId }, 'Using .slack-dev.json for workspace connection'); | |
| return buildDevWorkspaceConnection(devConfig, teamId); | |
| } | |
| logger.warn( | |
| { teamId }, | |
| 'Dev mode enabled (.slack-dev.json found) but config could not be loaded - falling back to production lookup' | |
| ); | |
| } |
Refs:
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
There was a problem hiding this comment.
PR Review Summary
(1) Total Issues | Risk: High
🔴❗ Critical (1) ❗🔴
Inline Comments:
- 🔴 Critical:
dev-config.ts:90Syntax error — extra closing brace prevents compilation
🕐 Pending Recommendations (4)
Previous issues from the prior review that remain unaddressed:
- 🔴
commands/index.ts:299-304Behavioral regression — tenant-scoped lookup replaces tenant-agnostic lookup, potentially breaking multi-tenant user resolution - 🟠
nango.ts:224-230Silent fallthrough when dev config is unreadable creates confusing failure modes - 🟡
dev-config.tsModule-level mutable state prevents test isolation (no cache reset function) - 🟡
dev-config.tsMissing tests for new module (~100 lines)
🚫 REQUEST CHANGES
Summary: The commit attempting to address the JSON parse logging feedback introduced a syntax error (extra } on line 90) that will prevent the code from compiling. Please remove the extra brace. Additionally, the critical tenant-lookup behavioral change and major silent-fallthrough issue from the previous review remain unaddressed.
Discarded (0)
No findings discarded in this delta review.
Reviewers (1)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
orchestrator |
1 | 0 | 0 | 0 | 1 | 4 | 0 |
| Total | 1 | 0 | 0 | 0 | 1 | 4 | 0 |
Note: This was a minimal delta review (1 file, 6 lines changed). Sub-agent reviewers were not dispatched due to the self-evident syntax error.
| return null; | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
🔴 CRITICAL: Syntax error — extra closing brace
Issue: Line 90 has an extra closing brace } that will cause a syntax/compilation error. This appears to have been introduced when applying the logging fix for the getDevDefaultAgent function.
Why: This will prevent the code from compiling and block all builds/deployments.
Fix:
| } |
Refs:
- The function
getDevDefaultAgentends correctly at line 89; line 90 should be removed entirely.
There was a problem hiding this comment.
PR Review Summary
(0) Total Issues | Risk: Low
This delta re-review (2 commits) validates that prior feedback has been addressed:
- ✅ Syntax error (extra
}) — fixed - ✅
resetDevConfigCache()missing — added atdev-config.ts:91-97 - ✅ Missing tests — comprehensive test file added (292 lines)
- ✅ Silent JSON parse failure — logging added to
getDevDefaultAgent - ✅ Silent fallthrough in dev mode — explicit
return nulladded atnango.ts:231
💭 Consider (1) 💭
💭 1) dev-config.test.ts TTL cache expiration behavior not directly tested
Issue: The tests verify caching works but don't test that config is re-read after the 5-second TTL expires.
Why: If a bug inverted the TTL comparison, changes to .slack-dev.json might not reflect for longer than expected. The resetDevConfigCache() function provides a workaround, and this is a dev-only feature.
Fix: Consider adding a test using vi.useFakeTimers() to advance past the TTL and verify re-read behavior.
Refs:
🕐 Pending Recommendations (1)
- 🟠
nango.ts:224-232Prior suggestion to uselogger.warnfor dev mode fallthrough — current implementation useslogger.debugand explicitreturn null, which is acceptable and follows existing patterns
🔄 Prior Review Corrections
The prior review's "Critical" tenant-lookup regression finding was a false positive. The change from findWorkAppSlackUserMapping (tenant-scoped) to findWorkAppSlackUserMappingBySlackUser (tenant-agnostic) in commands/index.ts was intentional and correct:
- The comment explains: "Find user mapping without tenant filter to get the correct tenant"
- The subsequent code uses
existingLink.tenantIdto resolve the user's actual tenant - This correctly handles multi-tenant scenarios where the workspace tenant and user tenant may differ
✅ APPROVE
Summary: All actionable feedback from prior reviews has been addressed. The new tests provide comprehensive coverage for the dev-config module. The PR is ready to merge. 🎉
Discarded (2)
| Location | Issue | Reason Discarded |
|---|---|---|
dev-config.ts:91 |
Cache reset function naming diverges from GitHub peer (resetDevConfigCache vs clearConfigCache) |
Semantic difference is intentional — Slack's reset clears multiple state variables (config + path + dev mode flags), while GitHub's clear only clears the config object |
nango.ts:230 |
Dev mode fallthrough uses logger.debug instead of suggested logger.warn |
Follows existing pattern for operational flow logging; the explicit return null prevents silent fallthrough to production Nango calls |
Reviewers (3)
| Reviewer | Returned | Main Findings | Consider | While You're Here | Inline Comments | Pending Recs | Discarded |
|---|---|---|---|---|---|---|---|
pr-review-standards |
0 | 0 | 0 | 0 | 0 | 0 | 0 |
pr-review-tests |
1 | 0 | 1 | 0 | 0 | 0 | 0 |
pr-review-consistency |
2 | 0 | 0 | 0 | 0 | 1 | 1 |
| Total | 3 | 0 | 1 | 0 | 0 | 1 | 1 |
No description provided.