[Bug]: Agent stream auto-aborts right after it starts (Aborting stream user-requested) — still reproducible on 2.0.14

Author: mowenQWQCreated Sep 15, 2026Updated Sep 17, 2026

Platform

  • OS: Windows 11 Home (win32-x64)
  • Version: 2.0.14
  • Product: Cherry Studio agent (Claude Code driver)

Summary

In an agent session, right after a new message triggers a fresh stream, the stream aborts on its own without any user action, then the Claude Code child process is killed (SIGKILL), leaving the assistant message stuck in paused/pending with 0 output chars. This has happened across many work sessions (both this morning's and the afternoon's log blocks), so it is reproducible, not a one-off hang.

Log evidence (app.2026-09-15.log.N, JSON-lines)

Pattern (times are local):

14:21:00  AiStreamManager/ClaudeCodeStreamAdapter  Stream session initialized
14:21:00  ProxyStreamService  Starting streaming message
14:21:04  AiStreamManager  Aborting stream  { reason: "user-requested", topicId: "agent-session:13361c9c-..." }
14:21:04  PersistenceListener  Assistant message persisted
14:21:11  AiStreamManager  Aborting stream  { reason: "gateway client disconnected" }
14:21:11  ModelRetry  model call failed after retries  The operation was aborted
14:21:11  ClaudeCodeProcessManager  Claude Code process failed  { exitSignal: "SIGKILL" }

So the timeline is: new stream starts → 4 seconds later it aborts as user-requested → 7 seconds later the process is SIGKILLed.

Counting across the whole day's logs: Claude Code process failed (SIGKILL) in app.2026-09-15.log.7 alone, each preceded ~7s by an Aborting stream user-requested on an agent-session: topic.

What can be ruled out (verified in the logs):

  • Not the 900 s timeout: no 900-second timeout event within 30 s before any of the SIGKILLs.
  • Not a permission / approval gate: zero permission/approval/deny log entries.
  • Not caused by my own automation (this one happened while the user was idle and I was only reading the DB/logs).

Suspected root cause (from source)

src/renderer/services/aiTransport/IpcChatTransport.ts:

if (abortSignal) {
  if (abortSignal.aborted) {
    ipcApi.request('ai.stream.abort', { topicId })
    closeStream()
    return
  }
  const onAbort = () => { ... }
  abortSignal.addEventListener('abort', onAbort, { once: true })
}

If an already-aborted AbortSignal is handed to a newly started stream, the branch at abortSignal.aborted fires immediately and self-cancels the fresh stream as user-requested. That matches the 4-second (start → abort) gap. Likely the previous stream's signal is being reused/reset incorrectly.

Steps to reproduce

  1. Use an agent session for a while (several messages back and forth).
  2. Send another message.
  3. Observe the assistant message landing in paused/pending with 0 content, and Aborting stream (user-requested) in the app log.

Workaround

  • Sending the next message in a new topic works (topic isolation sidesteps the stale signal).
  • Restarting Cherry before the next message also avoids it for a while.

Related

  • Likely same family as #18363 (AiStreamManager stale terminal callback root cause).
  • Similar to #19119 (empty stream / stuck after interrupting then resending).
  • Related to #16720 (stopped pending messages marked paused).

Appreciated if maintainers could double-check the AbortSignal lifecycle on stream start!


中文版

平台

  • 操作系统: Windows 11 Home (win32-x64)
  • Cherry Studio 版本: 2.0.14
  • 产品: Cherry Studio agent 会话(Claude Code 驱动)

概述

Agent 会话收到新消息后,新流启动仅 4 秒就被自动标记为 user-requested 并中止,随后 Claude Code 子进程被 SIGKILL 强杀,assistant 消息停在 paused/pending、0 字输出。该问题在今天多个时段稳定复现(凌晨、上午、下午各有多次),并非偶发。

日志铁证

日志路径 %APPDATA%\CherryStudio\logs\app.2026-09-15.log.N(JSON 行格式),关键时序:

14:21:00  AiStreamManager  Stream session initialized
14:21:00  ProxyStreamService  Starting streaming message
14:21:04  AiStreamManager  Aborting stream  reason="user-requested"  topicId="agent-session:xxx"
14:21:04  PersistenceListener  Assistant message persisted
14:21:11  AiStreamManager  Aborting stream  reason="gateway client disconnected"
14:21:11  ModelRetry  model call failed after retries  The operation was aborted
14:21:11  ClaudeCodeProcessManager  Claude Code process failed  exitSignal="SIGKILL"

全量统计 app.2026-09-15.log.7:6 次 Claude Code process failed (SIGKILL),每次前约 7 秒均有 Aborting stream user-requested

已排除的原因

  • ❌ 900 秒超时:每次 SIGKILL 前 30 秒内均无 900-second timeout 事件
  • ❌ 权限/审批:全量日志搜 permission/approval/deny = 0 条
  • ❌ 用户手动点停止:新流启动仅 4 秒就被 abort,且用户当时无任何操作

疑似根因(源码定位)

src/renderer/services/aiTransport/IpcChatTransport.ts

if (abortSignal) {
  if (abortSignal.aborted) {
    ipcApi.request('ai.stream.abort', { topicId })
    closeStream()
    return
  }
  // ...
}

如果新流启动时拿到的是一个已经被 abort 的 AbortSignalabortSignal.aborted 分支会立即触发 ai.stream.abort,把新流以 user-requested 理由杀掉。时间线(4 秒从启动到中止)与此完全吻合。

复现步骤

  1. 在 agent 会话里连续对话几轮
  2. 发送下一条消息
  3. 观察:assistant 消息停在 paused/pending,0 字输出;app 日志出现 Aborting stream user-requested + SIGKILL

规避方法

  • 新消息发到新 topic(topic 隔离可绕过 signal 复用)
  • 重启 Cherry 后立即发消息

关联 Issue

  • 同族:#18363(AiStreamManager 状态机 stale terminal callback 根因)
  • 类似:#19119(手动中断后重新生成返回空流/卡死)
  • 相关:#16720(stopped pending messages marked paused)