datawhalechina/hello-agents · error · Error

服务响应中断,请重试

Error message

服务响应中断,请重试

What it means

Thrown by runAgentMode in AutoFlow's frontend after streamAgentChat completes without ever receiving a terminal SSE event. The stream loop only sets settled=true on data.type === 'result' or 'error'; if the server closes the connection, the proxy drops it, or the stream emits only non-terminal 'status' frames, settled stays false and this generic interruption error is raised. It is a client-side liveness check over a server-sent-events chat stream, not a backend exception.

Source

Thrown at Co-creation-projects/usernamedadad-AutoFlow/frontend/src/App.jsx:243

              });
            }
            pushChatMessage(modeKey, {
              role: "assistant",
              content: data.mermaid_code || "",
              kind: "code",
              title: ASSISTANT_PREFIX[modeKey],
            });
          }

          if (data.type === "error") {
            settled = true;
            setError(data.message || "智能体执行失败");
          }
        }
      );

      if (!settled) {
        throw new Error("服务响应中断,请重试");
      }
    } finally {
      setThinkingMap((prev) => ({ ...prev, [modeKey]: false }));
    }
  };

  const handleGenerate = async () => {
    setLoading(true);
    setError("");
    setStatusText("请求处理中...");

    try {
      if (mode === "plan") {
        await runPlanMode();
      } else if (mode === "code") {
        await runCodeMode();
      } else {
        await runAgentMode();

View on GitHub (pinned to 606a07d341)

Solutions

  1. Check backend logs for the crashed/timed-out agent run and re-run the same prompt; the error is transient whenever the backend died mid-stream.
  2. Raise proxy read timeouts (e.g. nginx proxy_read_timeout, Vite server.proxy timeout) above the agent's worst-case generation time.
  3. Make the backend always emit a terminal frame: catch-all exception handler that writes {'type':'error','message':...} before closing the response.
  4. Add heartbeats/keepalive 'status' frames plus an explicit 'done' sentinel event so the client can distinguish slow progress from a dead stream.
  5. Implement exponential-backoff retry in runAgentMode when this error fires (idempotency-safe since no result was delivered).

Example fix

// before
if (!settled) {
  throw new Error("服务响应中断,请重试");
}

// after
if (!settled) {
  // distinguish network drop from backend error; allow auto-retry
  throw new StreamInterruptedError("服务响应中断,请重试", { retryable: true });
}
// caller: catch (e) { if (e.retryable && attempt < 2) return runAgentMode(attempt + 1); setError(e.message); }
Defensive patterns

Strategy: retry

Validate before calling

// Before streaming, confirm the endpoint is alive so dead-backend cases
// surface as a clear network error instead of a silent empty stream.
async function checkStreamEndpoint(url) {
  const res = await fetch(url, { method: 'HEAD' });
  if (!res.ok) throw new Error(`endpoint ${url} unreachable: ${res.status}`);
}

Try / catch

try {
  await streamAgentChat(payload, onEvent);
  if (!settled) throw new Error('服务响应中断,请重试');
} catch (e) {
  if (isTransient(e) && attempt < MAX_RETRIES) {
    await backoff(attempt); // 1s, 2s, 4s
    return run(attempt + 1);
  }
  setError(e.message || '请求失败');
}

Prevention

When it happens

Trigger: Calling streamAgentChat (POST to the agent chat endpoint with mode/prompt/direction) where the backend: crashes mid-run, times out after only emitting {'type':'status'} frames, is restarted during generation, or returns 200 but closes the body early. Also triggered if the SSE parser silently swallows malformed frames so the result event is never parsed.

Common situations: Long LLM generations exceeding reverse-proxy (nginx/Vite dev proxy) read timeouts; backend container OOM-killed mid-stream; dev server hot-reload dropping the EventSource/fetch stream; backend returning NDJSON lines the client parser cannot recognize; network switch mid-request on mobile.

Related errors


AI-assisted analysis of datawhalechina/hello-agents@606a07d341 (2026-08-14). Data as JSON: /api/errors/de2b757816c7af8c. Report an issue: GitHub.