CherryHQ/cherry-studio · error · Error
Channel not found: ${channelId}
Error message
Channel not found: ${channelId} What it means
Thrown by AgentJobsService.assertChannelsBelongToAgent when a referenced channel either does not exist (agentChannelService.getChannel returns falsy) or exists but its agentId does not match the expected agent. Each iteration of the channel list is checked; the first invalid channel throws. Like the agent-not-found guard, this is a plain Error because no renderer branch needs a specific not-found code.
Source
Thrown at src/main/ai/agents/AgentJobsService.ts:277
if (bound) agentTaskService.notifyReadModelChange([params.scheduleId])
return bound
}
// Plain Errors on purpose: no renderer branch consumes an agent/channel
// not-found code (the message reaches the toast through INTERNAL either
// way), so no AI-domain IpcError code is minted for them — unlike trigger
// validation, where the form must branch on the code.
private assertAgentExists(agentId: string): void {
if (!agentService.getAgent(agentId)) {
throw new Error(`Agent not found: ${agentId}`)
}
}
private assertChannelsBelongToAgent(agentId: string, channelIds: readonly string[]): void {
for (const channelId of channelIds) {
const channel = agentChannelService.getChannel(channelId)
if (!channel || channel.agentId !== agentId) {
throw new Error(`Channel not found: ${channelId}`)
}
}
}
}
View on GitHub (pinned to 726446b54c)
Solutions
- Confirm each channelId exists and belongs to the target agent before submitting (refresh the channel list for that agent).
- Remove or rebind triggers/schedules that reference deleted or reassigned channels.
- Invalidate UI-cached channel references when a channel is deleted or reassigned.
- Validate the channel list against the agent's current channels at form-submit time.
Defensive patterns
Strategy: validation
Validate before calling
// Confirm each channel exists and belongs to the agent before submitting
for (const id of channelIds) {
const ch = agentChannelService.getChannel(id)
if (!ch || ch.agentId !== agentId) {
throw new Error(`Channel '${id}' is missing or belongs to a different agent`)
}
} Type guard
const channelBelongsToAgent = (channelId: string, agentId: string): boolean => {
const ch = agentChannelService.getChannel(channelId)
return !!ch && ch.agentId === agentId
} Prevention
- Refresh the channel list for the agent before submitting triggers.
- On channel deletion/reassignment, cascade-update dependent triggers.
- Invalidate UI-cached channel references when channels change.
- Validate channel ownership at the service boundary, not only in the form.
When it happens
Trigger: Submitting a schedule/trigger that references a channelId which was deleted, never existed, or was reassigned to a different agent. The check is channel && channel.agentId === agentId, so a channel belonging to another agent also fails.
Common situations: Channel deleted while triggers still reference it; cross-agent contamination (channelId copied from a different agent's config); reassigning a channel to a new agent without updating existing triggers; stale channelId cached in the UI.
Related errors
- Agent not found: ${agentId}
- Unsupported agent runtime type: ${entry.agentType}
- Agent storage path escapes its root: ${target}
- Agent storage root must be a real directory: ${root}
- Agent storage path parent is not a directory: ${current}
AI-assisted analysis of CherryHQ/cherry-studio@726446b54c (2026-08-12).
Data as JSON: /api/errors/fa31a1e63a2916c3.
Report an issue: GitHub.