datawhalechina/hello-agents · error

Failed to submit sentence: ${response.statusText}

Error message

Failed to submit sentence: ${response.statusText}

What it means

Thrown by submitSentence() in the SentenceExpandAgent frontend when POST /api/session/submit returns a non-OK status. This call carries a user's manual-mode expansion sentence, so the error means the backend rejected the submission — most often because the session referenced by the request no longer exists server-side. Like its sibling startSession, it reports only statusText, which can be empty.

Source

Thrown at Co-creation-projects/xujikai-SentenceExpandAgent/frontend/src/api/expand.ts:49

  }

  return response.json();
}

/**
 * 提交用户扩写句子(手动模式)
 */
export async function submitSentence(request: SubmitRequest): Promise<AgentResponse> {
  const response = await fetch(`${API_BASE_URL}/api/session/submit`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(request),
  });

  if (!response.ok) {
    throw new Error(`Failed to submit sentence: ${response.statusText}`);
  }

  return response.json();
}

/**
 * 获取会话完整状态
 */
export async function getSession(sessionId: string): Promise<SessionState> {
  const response = await fetch(`${API_BASE_URL}/api/session/${sessionId}`);

  if (!response.ok) {
    throw new Error(`Failed to get session: ${response.statusText}`);
  }

  return response.json();
}

View on GitHub (pinned to 606a07d341)

Solutions

  1. Check the response status/body in DevTools: 404 on an existing session means server-side session store was reset — call startSession again to get a fresh session.
  2. Verify the SubmitRequest field names/types match the backend endpoint schema exactly.
  3. If sessions are in-memory on the backend, move them to a persistent store or add re-start logic on 404.
  4. Improve the thrown error to include status and body (see exampleFix) since statusText is often blank.

Example fix

// before
if (!response.ok) {
  throw new Error(`Failed to submit sentence: ${response.statusText}`);
}

// after
if (!response.ok) {
  const body = await response.text().catch(() => "");
  throw new Error(`Failed to submit sentence: ${response.status} ${body.slice(0, 200)}`);
}
Defensive patterns

Strategy: retry

Validate before calling

if (!request.session_id) {
  throw new Error('缺少 session_id,请先调用 startSession');
}
if (!request.sentence || !request.sentence.trim()) {
  throw new Error('扩写句子不能为空');
}

Type guard

function isSubmitRequest(r: unknown): r is SubmitRequest {
  return typeof r === 'object' && r !== null
    && typeof (r as SubmitRequest).session_id === 'string'
    && typeof (r as SubmitRequest).sentence === 'string';
}

Try / catch

try {
  await submitSentence(request);
} catch (err) {
  if ((err as Error).message.includes('404')) {
    // session lost server-side — restart and retry once
    const fresh = await startSession(baseRequest);
    await submitSentence({ ...request, session_id: fresh.session_id });
  } else {
    showError((err as Error).message);
  }
}

Prevention

When it happens

Trigger: POST {API_BASE_URL}/api/session/submit with a SubmitRequest whose session_id is unknown/expired (404), whose sentence fails validation (422), when the backend LLM call fails (500), or when the backend is unreachable through the proxy (502).

Common situations: Backend restarted or uses in-memory session storage so all session_ids are lost; user leaves the page open past session TTL; sentence payload field names mismatched between frontend type and backend schema.

Related errors


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