Repository navigation
Open
Description
环境 / 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
非确定性,但方向稳定:
- 插件 0.16.3 + DSH 0.2.1-rc.5,Go 计划,仅 CLI 登录态,不配 API key;
web.searchProvider设为commandcode;- 一次
web_search传入 4 个 query(DSH 会并发扇出); - 或在同一分钟内启动多个子代理各自搜索;
- 观察到约 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
- 插件的
CommandCodeSearchProvider.search()只发一次fetch,失败直接抛出,没有重试(lib/index.js的Command Code web search request failed分支)。 - 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." - 两者叠加:一次网络抖动 = 整批 query 失败,且不返回任何部分结果。
- 已排除相近 issue:
- 无法使用了 #59(代理变量导致
dsh-http-proxy安装 undici dispatcher):本机无任何代理变量; - 探活用 new URL("/", apiBase) 丢掉路径前缀,带前缀的 apiBase 一定误报;断连报错也不含目标 host:port #111(
apiBase带路径前缀的反代导致fetch failed):本机使用默认 apiBase,无反代。
- 无法使用了 #59(代理变量导致
影响 / Impact
- 并行研究类 workflow(多个子代理同时检索)容易整批丢结果,重跑成本高;
- 失败的搜索在面板显示 $0,但重试成功的每次按 $0.001 计费(见 commandcode 的网页搜索会消耗额度吗? #66);
- 用户无法从
fetch failed判断是网络、代理还是套餐问题。
建议 / Suggestions
- 给搜索请求加重试:2–3 次指数退避 + 抖动。搜索是幂等的,重试安全。
- 多 query 允许部分成功:每个 query 单独 try/catch,返回已完成结果 + 失败 query 的错误,不要 abort 兄弟请求。
- 错误串带原因和目标地址:例如
fetch failed (ECONNRESET, api.commandcode.ai:443, 21700ms),便于区分 DNS、连接重置和超时。 - 可选:把搜索超时做成配置项;复用 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:
- Plugin 0.16.3 + DSH 0.2.1-rc.5, Go plan, CLI login state only, no API key;
- Set
web.searchProvidertocommandcode; - Call
web_searchwith 4 queries in one call (DSH fans them out concurrently); - Or start several subagents that each search within the same minute;
- 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, notfetch 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
CommandCodeSearchProvider.search()performs a singlefetchand throws immediately on failure — no retry (theCommand Code web search request failedbranch inlib/index.js).- DSH's
dsh-tool-webruns 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." - Combined effect: one transient network hiccup kills the entire batch, and no partial results are returned.
- Related issues ruled out:
- 无法使用了 #59 (proxy env causing `d
Metadata
Metadata
Assignees
Labels
No labels
Activity
Mars-Sea commentedon Nov 3, 2026
@ben-bot-ai 看一下这个问题
ben-bot-ai commentedon Nov 3, 2026
收到:我来查一下 #117 里 web_search 多 query 并发时报 fetch failed 的问题。
ben-bot-ai commentedon Nov 3, 2026
This is by an automated agent, not a human.
已定位并修复,PR #118 的 CI 全绿,待你合并。根因是 undici 在收到 HTTP 状态前连接超时:插件单次 fetch 失败即抛,DSH 多 query 并发时一次抖动丢掉整批。修复为连接层失败重试(最多 3 次、指数退避)并在错误串带上原因、目标地址与耗时;多 query 部分成功属 DSH 上游策略,未在此插件修改。
fix(web-search): 连接层瞬时失败重试,并让 fetch failed 带原因与目标(#117)
docs(web-search): 补重试预算边界与响应体语义,取消测试改为确定性(#117)
docs(web-search): 修正产物 JSDoc 链接与取消测试措辞,补默认接线用例(#117)
Merge pull request #118 from Mars-Sea/agent/investigate-web-search-fa…
merge: 同步上游 web_search 连接层重试修复(Mars-Sea#117/Mars-Sea#118)