Skip to content

getPublicChannelIds is membership-scoped — same bug #249 fixed in refs.ts #263

Description

@scottlovegrove

Summary

getPublicChannelIds in src/lib/public-channels.ts builds its public-channel allowlist from client.channels.getChannels({ workspaceId }) only. That endpoint is membership-scoped — it excludes public channels the current user hasn't joined.

This is the same bug class that #249 fixed in resolveChannelRef (src/lib/refs.ts), but in a file #249 didn't touch.

// src/lib/public-channels.ts:12
const channels = await client.channels.getChannels({ workspaceId })
const publicIds = new Set<number>()
for (const ch of channels) {
    if (ch.public) publicIds.add(ch.id)
}

Impact

getPublicChannelIds feeds two callers:

  1. assertChannelIsPublic (public-channels.ts:25) — gates thread access. A thread in a public channel the user hasn't joined is wrongly rejected with NOT_FOUND: "This thread belongs to a private channel.", even though it's public and readable. This is the exact threads/get workaround path that the newsletter-crawler skill relies on.

  2. filterVisibleSearchResults (src/lib/search-helpers.ts:183) — client-side filter on search results. Practically masked today because the server /api/v3/search index is itself membership-scoped (returns zero for unjoined channels), so there's nothing to wrongly filter out. But it's latent: if/when search scope widens server-side, this filter would silently drop unjoined-public results.

Scale check (from #249): Doist workspace 1585 has 998 public channels, 829 of them unjoined for the test user — so this bites in production, not just edge cases.

Suggested fix

Mirror #249: merge getChannels with workspaces.getPublicChannels and dedupe by id. Same shape already used in src/commands/channel/list.ts:177-180 for the --scope public path.

Out of scope

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingreleased

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions