Clarify response semantics for deleted private channel APIs
- Dominant language
- Rust
- Stars
- 32.7k
- Forks
- 4.3k
- Avg merge
- 1d 13h
- Merged PRs (30d)
- 253
Description
## Summary
This is not intended as a definitive bug report. It is a request to clarify and potentially improve the consistency of API/CLI response semantics when operating on a deleted private channel UUID.
During testing, the same deleted private channel UUID produced different response shapes and error classifications across channel/message-related commands. If some ambiguity is intentional to avoid revealing private channel existence, it may still be useful to make the machine-readable response semantics consistent enough for clients and AI agents to handle the deleted private channel as an unavailable target.
## Reproduction Steps
1. Create a new private stream channel named `bug-test`.
2. Record the returned channel UUID.
3. Add a test user as `admin` so they can delete the channel during the test.
4. Wait 30 seconds and delete the channel during that interval.
5. Without re-searching for the channel, run several commands against the recorded, now-deleted UUID:
- send a message
- list channel members
- join the channel
- get channel metadata
The recorded UUID is anonymized below as:
```text
```
## Actual CLI Commands and Responses
### 1. Create the private channel
```bash
buzz channels create --name bug-test --type stream --visibility private
```
Response:
```json
{"accepted":true,"channel_id":"","event_id":"","message":""}
```
### 2. Add a test user as admin
```bash
buzz channels add-member --channel --pubkey --role admin
```
Response:
```json
{"accepted":true,"event_id":"","message":""}
```
### 3. Wait 30 seconds
```bash
sleep 30
```
Result:
```text
exit code 0
```
The channel was deleted during this interval.
### 4. Send a message to the deleted UUID
```bash
printf 'Hello\n' | buzz messages send --channel --content -
```
Response:
```json
{"error":"relay_error","message":"relay error 400: restricted: not a channel member","retryable":false}
```
Exit code: `2`
### 5. List members for the deleted UUID
```bash
buzz channels members --channel
```
Response:
```json
[]
```
Exit code: `0`
### 6. Join the deleted UUID
```bash
buzz channels join --channel
```
Response:
```json
{"error":"relay_error","message":"relay error 400: invalid: channel not found","retryable":false}
```
Exit code: `2`
### 7. Get channel metadata for the deleted UUID
```bash
buzz channels get --channel
```
Response:
```json
null
```
Exit code: `0`
## Observed Behavior
For the same deleted private channel UUID, the commands returned different representations:
- `messages send` -> `restricted: not a channel member` with exit code `2`
- `channels join` -> `channel not found` with exit code `2`
- `channels members` -> `[]` with exit code `0`
- `channels get` -> `null` with exit code `0`
A separate test that re-ran `buzz channels search --query bug-test --exact` after deletion returned an empty array, so this report is not claiming that search-index staleness was reproduced. The issue here is specifically the response semantics when a previously recorded deleted private channel UUID is used directly.
## Why This Can Be Difficult for Clients and AI Agents
Clients and AI agents often need to classify command results mechanically. In this case, the same deleted private channel can look like several different conditions depending on the API surface:
- authorization failure
- missing resource
- successful empty member list
- successful null metadata lookup
That makes it harder to write generic handling for delayed actions, stale references, and recovery flows. An agent may need command-specific heuristics to decide whether the deleted private channel UUID can still be used or should be treated as unavailable.
This matters especially for workflows where a channel UUID is captured, then a human or another actor deletes the channel before the agent acts. Revalidating immediately before use helps, but consistent deleted-private-channel semantics would still make fallback behavior simpler and safer.
## Expected / Suggested Behavior
How deleted private channels should be represented is a product/security design decision. For example, it may be intentional to avoid revealing the existence of private channels to unauthorized clients.
Even if exact human-readable error messages remain intentionally ambiguous, it would help if clients and AI agents could mechanically classify this deleted private channel case as the same general unavailable state. Possible approaches might include:
- returning a consistent exit code for deleted private channel targets;
- using a consistent structured error category or machine-readable reason/code;
- reserving `[]` and `null` for successful reads of existing resources, and using structured errors for unavailable deleted private channel resources; or
- clearly documenting that these commands intentionally differ and how clients should classify them.
This is not a request to force everything to return `restricted`. The main request is consistency or documentation for how clients should interpret the deleted private channel state.
Is this the intended behavior, or would you consider unifying the response semantics across these APIs?
Contributor guide
Research direction
Start by reproducing the four commands shown in the issue against a deleted private channel UUID: messages send, channels members, channels join, and channels get. Compare their JSON responses and exit codes, then inspect the relevant API and CLI entry points to determine whether the behavior is intentional. Done means the project has an agreed consistent machine-readable classification or clear documentation for these results.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, cli
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100