datawhalechina/hello-agents · error

研究请求失败,状态码:${response.status}

Error message

研究请求失败,状态码:${response.status}

What it means

Thrown by the deepresearch frontend's streaming helper (code/chapter14/helloagents-deepresearch) when POST {baseURL}/research/stream returns a non-OK status AND the response body is empty or unreadable (the body text is preferred as the message when present). It reports the numeric HTTP status, so the message doubles as the server's rejection code for the research-stream request that carries the user's research question.

Source

Thrown at code/chapter14/helloagents-deepresearch/frontend/src/services/api.ts:35

export async function runResearchStream(
  payload: ResearchRequest,
  onEvent: (event: ResearchStreamEvent) => void,
  options: StreamOptions = {}
): Promise<void> {
  const response = await fetch(`${baseURL}/research/stream`, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      Accept: "text/event-stream"
    },
    body: JSON.stringify(payload),
    signal: options.signal
  });

  if (!response.ok) {
    const errorText = await response.text().catch(() => "");
    throw new Error(
      errorText || `研究请求失败,状态码:${response.status}`
    );
  }

  const body = response.body;
  if (!body) {
    throw new Error("浏览器不支持流式响应,无法获取研究进度");
  }

  const reader = body.getReader();
  const decoder = new TextDecoder("utf-8");
  let buffer = "";

  while (true) {
    const { value, done } = await reader.read();
    buffer += decoder.decode(value || new Uint8Array(), { stream: !done });

    let boundary = buffer.indexOf("\n\n");

View on GitHub (pinned to 606a07d341)

Solutions

  1. Read the status in the message: 404 → fix baseURL/route; 422 → fix payload shape; 500/502 → inspect backend logs for the research pipeline failure.
  2. Verify the backend exposes POST /research/stream with SSE and that required env keys (search API, LLM key) are set server-side.
  3. Check DevTools Network for this request — the empty-body case means the server gave no explanation, so server logs are the only source.
  4. For 429s, add client-side throttling before starting a new research stream.

Example fix

// before
const errorText = await response.text().catch(() => "");
throw new Error(errorText || `研究请求失败,状态码:${response.status}`);

// after
const errorText = await response.text().catch(() => "");
throw new Error(errorText || `研究请求失败,状态码:${response.status} ${response.statusText}`);
Defensive patterns

Strategy: try-catch

Validate before calling

if (!payload || !payload.question?.trim()) {
  throw new Error('研究问题不能为空');
}
if (!('ReadableStream' in window) || !('body' in Response.prototype)) {
  throw new Error('当前浏览器不支持流式研究进度');
}

Type guard

function isResearchPayload(p: unknown): p is { question: string } {
  return typeof p === 'object' && p !== null && typeof (p as { question?: unknown }).question === 'string';
}

Try / catch

try {
  await streamResearch(payload, onProgress, { signal });
} catch (err) {
  const m = (err as Error).message;
  if (/429/.test(m)) showRateLimitNotice();
  else if (/\d{3}/.test(m)) showServerError(m);
  else if ((err as Error).name === 'AbortError') return; // user cancelled
  else showNetworkError();
}

Prevention

When it happens

Trigger: POST /research/stream with the research payload (and an optional abort signal) returns 404 (wrong baseURL or route), 422 (invalid research request payload), 429 (search/LLM rate limits upstream), 500 (deep-research pipeline crash), or the fetch was aborted and resolves unusually through the error path.

Common situations: baseURL env var pointing to the wrong origin; backend research pipeline failing on the first LLM/search call; upstream API keys missing on the server so it returns 500 with an empty body; reverse proxy rejecting long-lived SSE connections with 502.

Related errors


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