{"record":{"id":"474ef9675e919d4e","repo":"CherryHQ/cherry-studio","slug":"channel-not-found-channelid-474ef9","errorCode":null,"errorMessage":"Channel not found: ${channelId}","messagePattern":"Channel not found: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/ai/channels/ChannelMessageHandler.ts","lineNumber":773,"sourceCode":"      channelSessionId: channelRow?.sessionId ?? null,\n      trackerKey\n    })\n\n    const newSession = this.createSessionForChannel(agentId, channelId, channelRow ?? undefined)\n    channelService.updateChannel(channelId, { sessionId: newSession.id })\n    this.sessionTracker.set(trackerKey, newSession.id)\n    this.evictSessionTracker()\n    return newSession\n  }\n\n  private createSessionForChannel(\n    agentId: string,\n    channelId: string,\n    channel?: NonNullable<Awaited<ReturnType<typeof channelService.getChannel>>>\n  ): AgentSessionEntity {\n    const channelRow = channel ?? channelService.getChannel(channelId)\n    if (!channelRow) {\n      throw new Error(`Channel not found: ${channelId}`)\n    }\n    return agentSessionService.create({\n      agentId,\n      name: 'Channel session',\n      workspace: channelRow.workspace\n    })\n  }\n\n  private async collectStreamResponse(\n    session: AgentSessionEntity,\n    content: string,\n    abortController: AbortController,\n    adapter: ChannelAdapter,\n    chatId: string,\n    replyToMessageId?: string,\n    onAdmitted?: () => void\n  ): Promise<string> {\n    if (!session.agentId) {","sourceCodeStart":755,"sourceCodeEnd":791,"githubUrl":"https://github.com/CherryHQ/cherry-studio/blob/726446b54cd69ffe51a276638672f6d95ca0768c/src/main/ai/channels/ChannelMessageHandler.ts#L755-L791","documentation":"Thrown by ChannelMessageHandler.createSessionForChannel when neither a passed-in channel row nor channelService.getChannel(channelId) resolves to a channel. The handler needs the channel's workspace to create an agent session, so a missing channel row is a hard stop.","triggerScenarios":"createSessionForChannel(agentId, channelId, channel?) is called with no channel argument and channelService.getChannel(channelId) returns null — e.g. an inbound message references a channelId that was deleted or never created.","commonSituations":"A channel was deleted while messages were still inbound; an integration/webhook delivered a message for an unregistered channel; channelId mismatch (rename/typo); race between channel creation and first message.","solutions":["Verify the channel exists: `channelService.getChannel(channelId)` before dispatching.","If the channel was deleted, drop/ignore the inbound message and stop its adapter subscription.","Ensure channel rows are created (and committed) before the adapter starts receiving for that channelId.","Catch at the handler boundary and reply with / log a 'channel not configured' result instead of crashing the handler."],"exampleFix":"// before: assume the channel exists\nconst session = createSessionForChannel(agentId, channelId)\n\n// after: resolve up front and guard\nconst channel = channelService.getChannel(channelId)\nif (!channel) { logger.warn('Inbound for unknown channel', { channelId }); return }\nconst session = createSessionForChannel(agentId, channelId, channel)","handlingStrategy":"type-guard","validationCode":"const channel = channelService.getChannel(channelId)\nif (!channel) {\n  logger.warn('Inbound message for unknown channel', { channelId })\n  return // do not attempt to create a session\n}\nconst session = createSessionForChannel(agentId, channelId, channel)","typeGuard":"function channelExists(c: unknown): c is { id: string; workspace: unknown } {\n  return c != null && typeof (c as { id?: unknown }).id === 'string'\n}","tryCatchPattern":"try {\n  const session = createSessionForChannel(agentId, channelId)\n} catch (e) {\n  if (e instanceof Error && /Channel not found:/.test(e.message)) {\n    // drop the inbound message; stop the adapter subscription for the dead channel\n    logger.warn('Dropping inbound for missing channel', { channelId })\n  } else throw e\n}","preventionTips":["Create and commit channel rows before subscribing the adapter.","Tear down subscriptions when a channel is deleted.","Validate channelId on inbound messages before session creation."],"tags":["channels","not-found","sessions","lifecycle"],"backgroundTag":null,"analyzedSha":"726446b54cd69ffe51a276638672f6d95ca0768c","analyzedAt":"2026-08-12T17:30:37.448Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}