fix: guard unreadResp.data against null in channel threads command#224
Conversation
doistbot
left a comment
There was a problem hiding this comment.
This PR nicely fixes a crash in the channel threads command by adding a necessary null guard to the unread threads response. The implementation correctly handles valid empty states, and the included regression test ensures this stability is maintained. A few additional adjustments are recommended, specifically applying this same null guard to the inbox command, using assertBatchData on the primary threads response to prevent a similar crash, and simplifying the test mock setup by updating the setupClient helper.
When the workspace has no unread threads, `client.threads.getUnread` can return a batch response with `data: null`, causing an uncaught TypeError on `.map()`. Add a `?? []` fallback so the command treats all threads as read instead of crashing. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…/inbox Address review feedback on PR #224 now that #159 is merged: - Add `getOptionalBatchData` helper in `src/lib/api.ts` — returns `data` (or null) on success, throws via `assertBatchData` only on real API errors. Use for batch sub-requests where `data: null` with a success code is a valid empty state (e.g. `getUnread` when the workspace has zero unread threads). - `channel/threads.ts`: use `assertBatchData` for primary `threadsResp` so a failed `getThreads` sub-request surfaces an API error instead of crashing with `TypeError: .map is not a function`. Use `getOptionalBatchData` for `unreadResp` to preserve the "no unread = empty" valid state. - `inbox.ts`: switch `unreadResponse` from strict `assertBatchData` to `getOptionalBatchData` (fixes regression introduced by #159 where a workspace with zero unread threads would crash `tw inbox`). - `channel/threads.test.ts`: update `setupClient` to accept `unread: null`, add `code: 200` to batch mock fixtures, refactor the regression test to use the helper, and add a new test for the threads-batch-error path. - `inbox.test.ts`: add a regression test for the null-unread case. - Document the four batch helpers and when to use each in AGENTS.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
d973f86 to
ebc641c
Compare
|
Hey @lmjabreu — pushed a follow-up commit on top of your fix now that #159 is merged. Quick summary of the adjustments:
Functionally your original fix is preserved — the new helper just makes the pattern explicit and reusable. |
## [2.36.5](v2.36.4...v2.36.5) (2026-05-13) ### Bug Fixes * guard unreadResp.data against null in channel threads command ([#224](#224)) ([617a617](617a617))
|
🎉 This PR is included in version 2.36.5 🎉 The release is available on: Your semantic-release bot 📦🚀 |
|
✅ |
What
tw channel threads <name> --jsoncrashed with:Root cause
src/commands/channel/threads.ts:89called.map()directly onunreadResp.datawith no null guard:The SDK's
client.batch()returns{ code, data: null }when a sub-request fails or whengetUnreadreturns no data (e.g. the user has zero unread threads in the workspace). Calling.map()onnullthrows.Fix
One-line change — add
?? []so a null/undefineddatafalls back to an empty set, treating all threads as read:assertBatchData()was intentionally not used here — having no unread threads is a valid state, not an error.Test
Added a regression test to the existing
src/commands/channel/threads.test.tsthat mocks the batch response withdata: nullfor the unread sub-request and asserts the command resolves without throwing, with all threads markedisUnread: false.Verification
npm run type-check✅npm test✅ (587 tests, 0 failures)tw channel threads "Doist Component Library" --no-spinner --json