Skip to content

web_search 间歇性报 "fetch failed":多 query 并发批次必现/ web_search intermittently throws "fetch failed" — multi-query batches always fail #117

Open

Description

@MengboLi

环境 / Environment

项 值
插件 @mars-sea/dsh-commandcode-provider 0.16.3(当前最新)
DSH 0.2.1-rc.5
Node v24.16.0
OS Windows 10.0.19045 x64
套餐 Go,无 COMMANDCODE_API_KEY,走 CLI 登录态(~/.commandcode/auth.json)
apiBase 默认 https://api.commandcode.ai,无反代前缀
代理 无。进程内 HTTP_PROXY/HTTPS_PROXY/ALL_PROXY 为空;用户级与系统级均未设置;WinHTTP 为直连
Profile web,web.searchProvider 显式钉为 commandcode

现象 / Symptom

2026-11-03 09:23–09:33(UTC+8),14 次 web_search 工具调用中 3 次失败,报错为:

Command Code web search request failed: fetch failed

Command Code 面板对应记录:失败、21.738s、0 token、$0.0000。

关键统计:

  • 多 query 调用(一次 4 个 query):2 次调用,2 次全失败
  • 单 query 调用:12 次,1 次失败(约 8%)
  • 失败后立刻用同样的单 query 重试,全部成功
  • 失败集中在 09:23–09:33 这 10 分钟,正好是 6 个子代理并行检索的时段

复现 / Reproduction

非确定性,但方向稳定:

  1. 插件 0.16.3 + DSH 0.2.1-rc.5,Go 计划,仅 CLI 登录态,不配 API key;
  2. web.searchProvider 设为 commandcode;
  3. 一次 web_search 传入 4 个 query(DSH 会并发扇出);
  4. 或在同一分钟内启动多个子代理各自搜索;
  5. 观察到约 20 秒后报 fetch failed,且整批 query 一起失败。

单 query 串行调用很少失败;同样的 query 立刻重试通常成功。


证据 / Evidence

  • 报错发生在拿到 HTTP 状态之前,因此不是 401/403/429。若是套餐或密钥问题,应显示 HTTP 403 upgrade_required / HTTP 401,而不是 fetch failed。
  • 本机当前链路实测:DNS 解析到 3 个 Cloudflare 地址;TCP 443 三次分别为 265 / 217 / 216 ms。说明链路平时是通的,问题是间歇性的。
  • 21.7 秒的耗时更像连接/读取阶段挂住后失败(connect timeout,或 happy-eyeballs 对 IPv4/IPv6 各等一轮),不像服务端快速拒绝。
  • 失败时段与最多 6 个子代理并发检索重叠,疑似并发压力放大了问题。

分析 / Analysis

  1. 插件的 CommandCodeSearchProvider.search() 只发一次 fetch,失败直接抛出,没有重试(lib/index.js 的 Command Code web search request failed 分支)。
  2. DSH 的 dsh-tool-web 在多 query 时并发请求,第一个失败会 abort 其余并整体抛出。源码注释原文:"A failed search aborts its siblings, and this function waits for every search to settle before rethrowing the first failure."
  3. 两者叠加:一次网络抖动 = 整批 query 失败,且不返回任何部分结果。
  4. 已排除相近 issue:

影响 / Impact

  • 并行研究类 workflow(多个子代理同时检索)容易整批丢结果,重跑成本高;
  • 失败的搜索在面板显示 $0,但重试成功的每次按 $0.001 计费(见 commandcode 的网页搜索会消耗额度吗? #66);
  • 用户无法从 fetch failed 判断是网络、代理还是套餐问题。

建议 / Suggestions

  1. 给搜索请求加重试:2–3 次指数退避 + 抖动。搜索是幂等的,重试安全。
  2. 多 query 允许部分成功:每个 query 单独 try/catch,返回已完成结果 + 失败 query 的错误,不要 abort 兄弟请求。
  3. 错误串带原因和目标地址:例如 fetch failed (ECONNRESET, api.commandcode.ai:443, 21700ms),便于区分 DNS、连接重置和超时。
  4. 可选:把搜索超时做成配置项;复用 keep-alive 连接。

补充 / Notes

  • 0.16.3 是当前最新版本(仓库 2026-11-02 仍有提交)。
  • 需要的话我可以按上面的复现方式跑对照实验(单 query vs 多 query、不同并发度),或帮忙验证补丁。

English version

Environment

Item Value
Plugin @mars-sea/dsh-commandcode-provider 0.16.3 (latest)
DSH 0.2.1-rc.5
Node v24.16.0
OS Windows 10.0.19045 x64
Plan Go, no COMMANDCODE_API_KEY, CLI login state only (~/.commandcode/auth.json)
apiBase default https://api.commandcode.ai, no reverse-proxy prefix
Proxy none. HTTP_PROXY/HTTPS_PROXY/ALL_PROXY empty in-process; unset at user and machine scope; WinHTTP is direct
Profile web, web.searchProvider pinned to commandcode

Symptom

On 2026-11-03 between 09:23 and 09:33 (UTC+8), 3 of 14 web_search tool calls failed with:

Command Code web search request failed: fetch failed

The Command Code dashboard recorded the failed call as: failed, 21.738s, 0 tokens, $0.0000.

Key numbers:

  • Multi-query calls (4 queries per call): 2 calls, 2 failures (100%)
  • Single-query calls: 12 calls, 1 failure (~8%)
  • Retrying the same single query immediately afterwards succeeded every time
  • All three failures fell inside a 10-minute window that overlapped with 6 subagents searching concurrently

Reproduction

Non-deterministic, but the pattern is stable:

  1. Plugin 0.16.3 + DSH 0.2.1-rc.5, Go plan, CLI login state only, no API key;
  2. Set web.searchProvider to commandcode;
  3. Call web_search with 4 queries in one call (DSH fans them out concurrently);
  4. Or start several subagents that each search within the same minute;
  5. After roughly 20 seconds the call fails with fetch failed, and the whole batch fails together.

Single-query calls rarely fail; retrying the same query usually works.

Evidence

  • The error is raised before an HTTP status is received, so it is not 401/403/429. A plan or credential problem would surface as HTTP 403 upgrade_required / HTTP 401, not fetch failed.
  • Live network probe from the same machine: DNS resolves to 3 Cloudflare addresses; three TCP 443 connects took 265 / 217 / 216 ms. The path is normally healthy; the failures are intermittent.
  • The ~21.7 s duration looks like a connect/read stall (connect timeout, or happy-eyeballs waiting on both address families), not a fast server-side rejection.
  • The failure window overlapped with up to 6 subagents searching concurrently, which may amplify connection pressure.

Analysis

  1. CommandCodeSearchProvider.search() performs a single fetch and throws immediately on failure — no retry (the Command Code web search request failed branch in lib/index.js).
  2. DSH's dsh-tool-web runs multi-query searches concurrently and aborts siblings on the first failure, then rethrows it. Source comment: "A failed search aborts its siblings, and this function waits for every search to settle before rethrowing the first failure."
  3. Combined effect: one transient network hiccup kills the entire batch, and no partial results are returned.
  4. Related issues ruled out:

Activity

  1. Mars-Sea commented on Nov 3, 2026

    @Mars-Sea
    Owner

    @ben-bot-ai 看一下这个问题

  2. ben-bot-ai commented on Nov 3, 2026

    @ben-bot-ai
    Collaborator

    收到:我来查一下 #117 里 web_search 多 query 并发时报 fetch failed 的问题。

  3. ben-bot-ai commented on Nov 3, 2026

    @ben-bot-ai
    Collaborator

    This is by an automated agent, not a human.
    已定位并修复,PR #118 的 CI 全绿,待你合并。根因是 undici 在收到 HTTP 状态前连接超时:插件单次 fetch 失败即抛,DSH 多 query 并发时一次抖动丢掉整批。修复为连接层失败重试(最多 3 次、指数退避)并在错误串带上原因、目标地址与耗时;多 query 部分成功属 DSH 上游策略,未在此插件修改。

  4. added a commit that references this issue on Nov 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions